1036. atof
Extend atof to handle scientific notation of the form 123.45e-6 where a floating-point number may be followed by e or E and an optionally signed exponent.
Write a program to enter a string and call atof.
See also Exercise 4-2 in the textbook.
#include <stdio.h>
/***************************************************************/
/* */
/* DON'T MODIFY main function ANYWAY! */
/* */
/***************************************************************/
double atof(char s[]) {
// TODO: your function definition
}
#define MAXLINE 80 /* maximum input line length */
int main() {
char s[MAXLINE];
scanf("%s", s);
printf("%f\n", atof(s));
}
样例
Input |
---|
123.45e-6 |
Output |
---|
0.000123 |
题解:
本题的数据卡得非常死,并且题面也没有给出很明确的数据提示,以至于会出现1e+03
这样的妖孽数据。一个个特判吧。
代码:
#include <stdio.h>
double atof(char s[])
{
int i = 0;
int foundE = 0;
int foundDot = 0;
//特判是否存在'e'和'.'
while (s[i] != '\0'){
if (s[i] == 'e' || s[i] == 'E') foundE = 1;
if (s[i] == '.') foundDot = 1;
i++;
}
double integerPart = 0;
int index = 0;int temp = 0;int sig = 1;
i = 0;
//特判负数情况
if (s[i] == '-'){sig = -1;i++;}
while (!foundDot && s[i] != 'e' && s[i] != 'E' && s[i] != '\0'){integerPart = integerPart * 10 + (int)s[i] - 48;i++;}
while (foundDot && s[i] != '.'){integerPart = 10 * integerPart + (int)s[i] - 48;i++;}
if(foundDot)i++;
while ((foundE && s[i] != 'e' && s[i] != 'E' && s[i] != '\0') || (!foundE && s[i] != '\0')){integerPart = 10 * integerPart + (int)s[i] - 48;i++;index--;}
if (foundE && s[++i] == '-'){
i++;
while (s[i] != '\0'){temp = 10 * temp + (int)s[i] - 48;i++;}
index -= temp;
}
else if (foundE){
while (s[i] == 0 || s[i] == '+') i++;
while (s[i] != '\0'){temp = 10 * temp + (int)s[i] - 48;i++;}
index += temp;
}
if (index > 0){for (int i = 0; i < index; i++) integerPart *= 10;}
else{for (int i = 0; i < -1 * index; i++) integerPart /= 10;}
if (sig > 0) return integerPart;
else return -1 * integerPart;
}
#define MAXLINE 80
int main()
{
char s[MAXLINE];
scanf("%s", s);
printf("%f\n", atof(s));
return 0;
}
1037. RPN calculator
Extend the program for reverse polish notation calculator to add the modulus (%) operator and provisions for negative numbers.
See also Exercise 4-3 in the textbook.
样例
Input |
---|
6 7 * 5 - |
Output |
---|
37 |
题解
计算逆波兰表达式最常用也是最好用的方法,就是使用“栈”这一数据结构。
算法描述:
1) 碰到数字,入栈; 2) 碰到运算符,弹出两次数字,计算得到的答案入栈; 3) 反复执行上面两个步骤; 4) 弹出最终结果。
注意事项:
本题需要同时读入数字和符号,同时,因为空格符号的存在,如果对数据类型的理解不够深入,建议采用getchar()进行读入。如果使用scanf("%s",s)
会导致读到第一个空格处就停止读入了。
PS:但是或许可以反复执行scanf,对每一个字符串分别处理之后再进行操作?
代码
代码描述:
我写了一个可以计算多位整数的程序,或许数据要求只要计算个位数就行了,但题面并没有写清楚。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Stack{
int num[1001];
int top;
int size;
}S;
void push(S* s, int num){s->num[s->top] = num; s->top--; s->size++;}
int pop(S* s){if(s->size) {s->size--; return s->num[++s->top];}}
long long calc(S* s, char a[]){
for(int i = 0; i < strlen(a); i++){
int sig = 1;int num = 0;int isNum = 0;
if(a[i] == '-'){
if(a[i + 1] != ' ' && a[i + 1] != '\0'){sig = -1;i++;}
else{
int temp1 = pop(s);
int temp2 = pop(s);
push(s, temp2-temp1);
}
}
while(a[i] <= '9' && a[i] >= '0'){
isNum = 1;
num = num*10 + a[i]-48;
i++;
}
if(isNum) push(s, num*sig);
if(a[i] == '+'){
int temp1 = pop(s);
int temp2 = pop(s);
push(s, temp2+temp1);
}
if(a[i] == '*'){
int temp1 = pop(s);
int temp2 = pop(s);
push(s, temp2*temp1);
}
if(a[i] == '/'){
int temp1 = pop(s);
int temp2 = pop(s);
push(s, temp2/temp1);
}
if(a[i] == '%'){
int temp1 = pop(s);
int temp2 = pop(s);
push(s, temp2%temp1);
}
}
return(pop(s));
}
int main(){
S* s = (S*)malloc(sizeof(S));
s->top = 1000;
s->size = 0;
char a[1001] = {'\0'};
char ch;
int i = 0;
while((ch = getchar())!='\n')a[i++] = ch;
printf("%lld\n", calc(s,a));
return 0;
}
1038. reverse string
Write a recursive version of the function reverse(s), which reverses the string in place.
Write a program to enter a string and call reverse(s).
See also Exercise 4-13 in the textbook
#include <stdio.h>
#include <string.h>
/***************************************************************/
/* */
/* DON'T MODIFY main function ANYWAY! */
/* */
/***************************************************************/
void reverse(char s[]) {
// TODO: your function definition
}
#define MAXLINE 80 /* maximum input line length */
int main() {
char s[MAXLINE];
scanf("%s", s);
//********** reverse is called here *************
reverse(s);
//**************************************************
printf("%s", s);
}
样例
Input |
---|
ecnu |
Output |
---|
unce |
题解
这题要求是用递归完成原地倒序,但只给用一个参数,似乎普通的递归需要至少两个参数?三个就更好写了。但是没办法,题目要求如此。 我这里是开了全局变量,用指针移位的操作来完成递归,看不懂的话可以了解一下什么是指针,指针和数组有什么关系。
代码
#include <stdio.h>
#include <string.h>
char *p;
int flag = 1;
void reverse(char s[]){
char temp;
if(flag){p = s+strlen(s)-1; flag = 0;}
if(s==p) return;
else{
temp = *s;*s = *p;*p = temp;p--;
if(s==p) return;
reverse(s+1);
}
}
#define MAXLINE 80
int main()
{
char s[MAXLINE];
scanf("%s",s);
reverse(s);
printf("%s",s);
return 0;
}
的确可以scanf(“%s”,s),每次读一个东西,再写一个判断是否是数字的函数(现在看来只需要判断是不是操作符?),是数字入栈(标准库有atoi函数将字符串转化为对应的int),是运算符进行出栈入栈操作
试了下,确实比getchar好写不少
我的1038(非指针)
void reverse(char s[]) {
char media;
static int cnt = 0;
int i = 0 + cnt;
int j = strlen(s) – 1 – cnt;
media = s[i];
s[i] = s[j];
s[j] = media;
cnt ++;
if (cnt < strlen(s) / 2) reverse(s);
}
牛的,这个static很妙
但是有一个小问题,这个函数虽在反复调用自己,但其实形式还是循环,而非递归。