TA2017_5

总结:

  • 字符串结束一定要加’\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(2n1)xPolyn1(x)n1nPolyn2(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;

}

运行结果:
这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值