总结:
字符串结束一定要加’\0’
函数的提取,主要是面向过程
递归函数注意执行顺序
表达式结束一定加‘;’
5_9 输入一行字符,统计其中的单词个数,
/**
* 输入一行字符,统计其中的单词个数,
** 单词之间可能会有多个空格
*/
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int countWords(char *str);
int main5_9()
{
char str[80];
while (true){
gets(str);
if ('\0' == str[0]) break;
int count = countWords(str);
printf("the number of words in this line is %d\n", count);
}
getchar();
getchar();
return 0;
}
int countWords(char *str){
int count = 0;
int i = 0;
int flag = 0; // 标志上一个字符是否为字母 0:not
while (*(str+i)){
if (!isalpha(*(str + i))){
flag = 0;
}
else if(0 == flag){
++count;
flag = 1;
}
++i;
}
return count;
}
运行结果:
5_10 输入两个字符串str1和str2,计算str2在str1中出现的位置(从0开始计算)
感兴趣的可以看看KMP算法
/**
* 输入两个字符串str1和str2,计算str2在str1中出现的位置(从0开始计算)
** eg:str1="how are you!",str="are",那么位置应该是4
*/
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int searchPos(char *str1, char *str2);
int main5_10()
{
char str1[80], str2[80];
while (true){
gets(str1);
if ('\0' == *str1) break;
gets(str2);
int pos = searchPos(str1, str2);
if (pos >= 0)
printf("the pos is %d\n", pos);
else
printf("not fount\n");
}
getchar();
return 0;
}
/**
* 从str1中查找str2,返回第一次匹配的位置
*/
int searchPos(char *str1, char *str2)
{
const int len1 = strlen(str1);
const int len2 = strlen(str2);
for (int pos = 0; pos <= len1-len2; ++pos){
if (*(str1 + pos) == *str2){
int j = 1;
while( (*(str2 + j) == *(str1 + pos + j)) && j<len2 ) ++j;
if (len2 == j) return pos;
}
}
return -1;
}
运行结果:
1. 写一个程序,将字符串 str1 中的原音字母复制到另一个字符串 str2,然后输出 str2
/**
* 写一个程序,将字符串 str1 中的原音字母复制到另一个字符串 str2,
* 然后输出 str2。
*/
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int isVowel(char ch);
int strcpyVowel(char *str1, char *str2);
int main(){
char str1[80], str2[80];
gets(str1);
strcpyVowel(str1, str2);
puts(str2);
getchar();
getchar();
return 0;
}
int strcpyVowel(char *str1, char *str2)
{
int idx = 0, count = 0;
while (*(str1+idx) != '\0'){
if (isVowel( *(str1 + idx) ) ){
*(str2 + count) = *(str1 + idx);
++count;
}
++idx;
}
*(str2 + count) = '\0';
return count;
}
int isVowel(char ch)
{
char c = tolower(ch);
if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') return 1;
return 0;
}
运行结果:
2. 写一个程序,将一个十进制数 N 转换成指定进制数(二进制,八进制或十六进制)的函数,输出转换后的数。
/**
* 写一个程序,将一个十进制数 N 转换成指定进制数
*(二进制,八进制或十六进制)的函数,输出
* 转换后的数
** 十进制数 N 由键盘输入, 紧接着输入另一个数(输入 1 表示转换二进制, 输入 2 表示转换八进
** 制, 输入 3 表示转换十六进制)
*/
#include <stdio.h>
#include <string.h>
int change(int num, int m, char *ans);
void reverse(char *str, int len);
int main()
{
int num = 0, m = 0;
scanf("%d%d", &num,&m);
char ans[80]="ans";
if (m >= 1 && m <= 3){
change(num, m, ans);
}
puts(ans);
getchar();
getchar();
return 0;
}
int change(int num, int m, char *ans)
{
int PROG[] = { 2, 8, 16 };
char *TABLE = "0123456789ABCDEF";
int _m = PROG[m - 1];
int count = 0;
do{
int idx = num%_m;
*(ans + count) = *(TABLE + idx);
++count;
num /= _m;
} while (num != 0);
*(ans + count) = '\0';
reverse(ans, count);
return count;
}
void reverse(char *str, int len)
{
for (int i = 0; i < (len>>1); ++i){
char temp = *(str + i);
*(str + i) = *(str + len - 1 - i);
*(str + len - 1 - i) = temp;
}
}
运行结果:
3.写一个程序,将字符串 str1 中最长的单词输出,此字符串由 main 函数以参数形式传递给该函数。
/**
* 写一个程序,将字符串 str1 中最长的单词输出,此字符串由 main 函数以参数形式传递给该函数
** 默认字符串中只包含小写字母和空格,单词由空格分隔,而且保证两单词中间有且仅有一个空格,
** 字符串首尾不包含空格
** 若有多个单词长度相等,输出在字符串中位置最靠前的一个
*/
#include <stdio.h>
#include <string.h>
int findLongestWord(char *str, char *word);
int main()
{
char str[80];
char word[80];
gets(str);
findLongestWord(str, word);
puts(word);
getchar();
getchar();
return 0;
}
/**
* 找到str中最长的单词, 保存在word中
* 返回长度
** 记录一个开始值和长度就可以确定一个单词
*/
int findLongestWord(char *str, char *word)
{
int maxStart = 0, maxLen = 0;
int currStart = 0, currLen = 0;
for (int i = 0; ; ++i){
if (*(str + i) != ' '&& *(str + i) != '\0'){
++currLen;
}
else{
// 先保存长度最长的结果
if (currLen > maxLen){
maxLen = currLen;
maxStart = currStart;
}
// 为下一次查找做准备
if (*(str + i) == '\0') break;
currStart = i + 1;
currLen = 0;
}
}
// 根据maxStart,maxLen确定单词
for (int i = maxStart, j = 0; j < maxLen; ++i, ++j){
*(word + j) = *(str + i);
}
*(word + maxLen) = '\0';
return maxLen;
}
运行结果:
4.写一个程序,找出 100~1000 以内的可逆素数
/**
* 写一个程序,找出 100~1000 以内的可逆素数
* eg 113,311 算两个
*/
#include <stdio.h>
int findRevPrime(int *arr);
int reverse(int num);
const int ST = 100;
const int EN = 1000;
int main()
{
int arr[EN] = { 0 };
int count = findRevPrime(arr);
for (int i = 0; i < count; ++i){
printf("%c %5d", i % 5 == 0 ? '\n' : ' ', arr[i]);
}
getchar();
getchar();
return 0;
}
/**
* 先找到所有素数,再确定是否可逆
** 结果放在arr中,返回总个数
*/
int findRevPrime(int *arr){
int flag[EN + 1] = {0}; // 标示是否为素数
int prime[EN + 1]; // 存放所有素数
for (int idx = 2; idx <= EN; ++idx) // 假设所有的都是素数
*(flag + idx) = 1;
int count = 0;
for (int i = 2; i <= EN; ++i){
if (1 == *(flag + i)){
prime[count++] = i;
}
for (int j = 0; j < count && prime[j] * i <= EN; ++j){
flag[prime[j] * i] = 0; // 素数的倍数则为合数,prime[j]为该合数的最小质因子
if (0 == i%prime[j]) break;
}
}
// 开始判断逆序,一次输出一对
count = 0;
for (int i = ST; i <= EN; ++i){
if (*(flag + i) ){
int rev = reverse(i);
if (i == rev){ // 去重 101, 101情况
arr[count++] = i;
}
else if (*(flag + rev)){
arr[count++] = i;
arr[count++] = rev;
flag[rev] = 0; // 减少后面计算, eg113, 就可不用判断311
}
}
}
return count;
}
int reverse(int num)
{
int rev = 0;
while (num){
rev *= 10;
rev += num % 10;
num /= 10;
}
return rev;
}
运行结果:
5.写一个函数,用递归的方法计算 n 阶勒让德多项式的值
公式如下:
Polyn(x)=⎧⎩⎨⎪⎪1Poly1(x)=x(2n−1)x−Polyn−1(x)−n−1nPolyn−2(x)n=0n=1n>1
/**
* n 阶勒让德多项式求值
* 迭代法和递归法
* @time:17.11.09
* @author:icesongqiang
*/
#include <stdio.h>
#include <stdlib.h> // for srand()
#include <malloc.h> // for malloc() && free()
#include <time.h> // for time()
#include <math.h> // for fabs()
#include <assert.h> // for assert()
/**
* 区分一次项和常数项, 按公式递推
* 可以再优化,只保留上两次的系数,不用保留所有的
* n: n阶多项式 int
* coefficient: 保存函数的系数 double *
*/
void process(int n, double *coefficient)
{
double *primary = (double *)malloc((n + 1)*sizeof(double));
double *constant = (double *)malloc((n + 1)*sizeof(double));
for (int i = 0; i <= n; ++i){
if (0 == i){
*(primary + i) = 0;
*(constant + i) = 1;
}else if (1 == i){
*(primary + i) = 1;
*(constant + i) = 0;
}else{
//iteration
*(primary + i) = (2 * i - 1) - *(primary + i - 1) - *(primary + i - 2)*(i - 1) / i;
*(constant + i) = - *(constant + i - 1) - *(constant + i - 2) * (i - 1) / i;
}
}
*coefficient = *(primary + n);
*(coefficient + 1) = *(constant + n);
for (int i = 0; i <= n; ++i){
*(primary + i) = NULL;
*(constant + i) = NULL;
}
free(primary);
free(constant);
return;
}
/**
***迭代法***
* n 阶 求函数值
* 0. 先求系数
* 1. 在计算函数值
*/
double poly_it(int n, double x){
double coe[2] = { 0, 0 };
process(n, coe);
return *coe * x + *(coe + 1);
}
/**
***递归法***
* 根据定义调用函数即可
*/
double poly_re(int n, double x){
if (n == 0) return(1);
else if (n == 1) return(x);
else return((2 * n - 1)*x - poly_re(n - 1, x) - (n - 1)*poly_re(n - 2, x) / n);
}
int main()
{
const int MAX_X = 20;
const int MAX_N = 10;
int i = 100;
srand((unsigned)time(0));
int count = 0;
while(i--){
double x = int(rand()) % MAX_X;
int n = int(rand()) % MAX_N;
double ans = poly_it(n, x);
double ans1 = poly_re(n, x);
if (fabs(ans-ans1)<1e-6){
printf("x = %lf, n= %d, ans = %lf\n", x, n, ans);
}else{
++count;
printf("x = %lf, n= %d, ans = %lf, ans1 = %lf\n", x, n, ans, ans1);
}
}
printf("\n %d error(s).\n", count);
system("pause");
return 0;
}
运行结果: