翁恺老师C语言课程作业代码的C/C++实现(下)

博客围绕C和C++语言,介绍了多个字符/字符串相关算法题,包括数素数、查找整数、求矩阵局部极大值等,给出各题输入输出格式及样例,并提供了C和C++的实现代码,最后鼓励读者刷题和关注后续更新。

5.字符/字符串(接中)

5.6数素数

        令Pi表示第i个素数。现任给两个正整数M <= N <= 104,请输出PM到PN的所有素数。

        输入格式:

输入在一行中给出M和N,其间以空格分隔。

        输出格式:

输出从PM到PN的所有素数,每10个数字占1行,其间以空格分隔,但行末不得有多余空格。

        输入样例:
5 27
        输出样例:
11 13 17 19 23 29 31 37 41 43
47 53 59 61 67 71 73 79 83 89
97 101 103

C语言实现:

#include <stdio.h>

int main() {
    int m, n, i, j, flag = -1, sum = 0, cnt = 0;
    scanf("%d %d", &m, &n);

    for (i = 2; i < 10000; i++) {
        flag = -1;
        for (j = 2; j < i; j++) {
            if (i % j == 0) {
                flag = 1;
                break;
            }
        }
        if (flag == 1) {
            continue;
        }
        sum += 1;
        if (sum >= m && sum <= n) {
            printf("%d ", i);
            cnt += 1;
        }
        if (cnt % 10 == 0 && cnt != 0) {
            printf("\n");
        }
    }
    return 0;
}

C++实现:

#include<iostream>
using namespace std;
int main(){
    int m,n,i,j,flag=-1,sum=0,cnt=0;
    cin>>m>>n;

    for(i=2;i<10000;i++){
        flag=-1;
        for(j=2;j<i;j++){
            if(i%j==0){
                flag=1;
                break;}
        } 
        if(flag==1)
            continue; 
        sum+=1;
        if(sum>=m && sum<=n){
            cout<<i<<" ";
            cnt+=1;
        }  
        if(cnt%10==0 && cnt!=0)
            cout<<endl;
    }
}

5.7查找整数

        本题要求从输入的N个整数中查找给定的X。如果找到,输出X的位置(从0开始数);如果没有找到,输出“Not Found”。

        输入样例1:

5 7
3 5 7 1 9

        输出样例1:

2
        输入样例2:

5 7
3 5 8 1 9

        输出样例2:

Not Found

C语言实现:

#include <stdio.h>

int main() {
    int m, n, i;
    int flag = -1;

    // 读取输入
    scanf("%d %d", &m, &n);
    int a[m];
    for (i = 0; i < m; i++) {
        scanf("%d", &a[i]);
    }

    // 查找特定元素
    for (i = 0; i < n; i++) {
        if (a[i] == n) {
            printf("%d\n", i + 1);
            flag = 1;
            break;
        }
    }

    // 输出结果
    if (flag == -1) {
        printf("ERROR\n");
    }

    return 0;
}

C++实现:

#include<iostream>
using namespace std;
int main(){
    int m,n,i;
    int flag=-1;
    cin>>m>>n;
    int a[m];
    for(i=0;i<m;i++){
        cin>>a[i];
    }
    for(i=0;i<n;i++)
        if(a[i]==n){
            cout<<i+1<<endl;
            flag=1;
            break;
    }
    if(flag==-1)
        cout<<"ERROR"<<endl;
    return 0;
}


5.8求一批整数中出现最多的个位数字

        给定一批整数,分析每个整数的每一位数字,求出现次数最多的个位数字。例如给定3个整数1234、2345、3456,其中出现最多次数的数字是3和4,均出现了3次。

        输入格式:

输入在第1行中给出正整数N(<=1000),在第2行中给出N个不超过整型范围的正整数,数字间以空格分隔。

        输出格式:

在一行中按格式“M: n1 n2 ...”输出,其中M是最大次数,n1、n2、……为出现次数最多的个位数字,按从小到大的顺序排列。数字间以空格分隔,但末尾不得有多余空格。

        输入样例:
3
1234 2345 3456

        输出样例:
3: 3 4

C语言实现:

#include <stdio.h>

int main() {
    int a[10], b[60], c[10] = {0};
    int n, i, j, t;
    scanf("%d", &n);

    // 读取输入
    for (i = 0; i < n; i++) {
        scanf("%d", &a[i]);
    }

    // 将每个数字分解为各个位数
    j = 0;
    for (i = 0; i < n; i++) {
        for (; a[i] > 0; j++) {
            b[j] = a[i] % 10;
            a[i] /= 10;
        }
    }
    j--;

    // 统计各个数字出现的次数
    for (; j >= 0; j--) {
        switch (b[j]) {
            case 0: c[0]++; break;
            case 1: c[1]++; break;
            case 2: c[2]++; break;
            case 3: c[3]++; break;
            case 4: c[4]++; break;
            case 5: c[5]++; break;
            case 6: c[6]++; break;
            case 7: c[7]++; break;
            case 8: c[8]++; break;
            case 9: c[9]++; break;
        }
    }

    // 找到出现次数最多的数字
    int max = 1;
    for (i = 0; i <= 9; i++) {
        if (max < c[i]) {
            max = c[i];
        }
    }

    // 输出结果
    printf("%d:", max);
    for (i = 0; i <= 9; i++) {
        if (c[i] == max) {
            printf("%d ", i);
        }
    }

    return 0;
}

C++实现:

#include<iostream>
using namespace std;
int main(){
    int a[10],b[60],c[10]={0};
    int n,i,j,t;
    cin>>n;
    for(i=0;i<n;i++){
        cin>>a[i];
    }

    j=0;
    for(i=0;i<n;i++){
        for(;a[i]>0;j++){
            b[j]=a[i]%10;
            a[i]/=10;
        }
    }
    j--;
    for(;j>=0;j--){
        switch(b[j]){
            case 0:c[0]++;break;
            case 1:c[1]++;break;
            case 2:c[2]++;break;
            case 3:c[3]++;break;
            case 4:c[4]++;break;
            case 5:c[5]++;break;
            case 6:c[6]++;break;
            case 7:c[7]++;break;
            case 8:c[8]++;break;
            case 9:c[9]++;break;
        }
    }
    int max=1;
    for(i=0;i<=9;i++){
        if(max<c[i])
            max=c[i];
    }
    cout<<max<<":";
    for(i=0;i<=9;i++){
        if(c[i]==max)
        cout<<i<<" ";
    } 
}

5.9求矩阵的局部极大值

        给定M行N列的整数矩阵A,如果A的非边界元素A[i][j]大于相邻的上下左右4个元素,那么就称元素A[i][j]是矩阵的局部极大值。本题要求给定矩阵的全部局部极大值及其所在的位置。

        输入格式:

输入在第1行中给出矩阵A的行数M和列数N(3<=M,N<=20);最后M行,每行给出A在该行的N个元素的值。数字间以空格分隔。

        输出格式:

每行按照“元素值 行号 列号”的格式输出一个局部极大值,其中行、列编号从1开始。要求按照行号递增输出;若同行有超过1个局部极大值,则该行按列号递增输出。若没有局部极大值,则输出“None 总行数 总列数”。

        输入样例1:
4 5
1 1 1 1 1
1 3 9 3 1
1 5 3 5 1
1 1 1 1 1

        输出样例1:
9 2 3
5 3 2
5 3 4

        输入样例2:
3 5
1 1 1 1 1
9 3 9 9 1
1 5 3 5 1

        输出样例2:
None 3 5

C语言实现:

#include <stdio.h>

int main() {
    int m, n, i, j;
    scanf("%d %d", &m, &n);
    int a[m][n];

    // 读取输入
    for (i = 0; i < m; i++) {
        for (j = 0; j < n; j++) {
            scanf("%d", &a[i][j]);
        }
    }

    // 检查局部最大值
    for (i = 1; i < m - 1; i++) {
        for (j = 1; j < n - 1; j++) {
            if (a[i][j] > a[i - 1][j] && a[i][j] > a[i + 1][j] && a[i][j] > a[i][j - 1] && a[i][j] > a[i][j + 1]) {
                printf("%d%d%d\n", a[i][j], i + 1, j + 1);
            }
        }
    }

    return 0;
}

C++实现:

#include<iostream>
using namespace std;
int main(){
    int m,n,i,j;
    cin>>m>>n;
    int a[m][n]={0};
    for(i=0;i<m;i++){
        for(j=0;j<n;j++){
            cin>>a[i][j];
        }
        cout<<endl;
    }
    for(i=1;i<m-1;i++){
        for(j=1;j<n-1;j++){
            if(a[i][j]>a[i-1][j]&&a[i][j]>a[i+1][j]&&a[i][j]>a[i][j-1]&&a[i][j]>a[i][j+1]){
                cout<<a[i][j]<<i+1<<j+1<<endl;
            }
        }
    }
}


 

5.10.组个最大值

        给定数字0-9各若干个。你可以以任意顺序排列这些数字,但必须全部使用。目标是使得最后得到的数尽可能小(注意0不能做首位)。例如:给定两个0,两个1,三个5,一个8,我们得到的最小的数就是10015558。

        现给定数字,请编写程序输出能够组成的最小的数。

        输入格式:

每个输入包含1个测试用例。每个测试用例在一行中给出10个非负整数,顺序表示我们拥有数字0、数字1、……数字9的个数。整数间用一个空格分隔。10个数字的总个数不超过50,且至少拥有1个非0的数字。

        输出格式:

在一行中输出能够组成的最小的数。

        输入样例:
2 2 0 0 0 3 0 0 1 0
        输出样例:
10015558

C语言实现:

 #include <stdio.h>

int main() {
    int a[10];

    // 读取输入
    for (int i = 0; i <= 9; i++) {
        scanf("%d", &a[i]);
    }

    // 输出最小的非零数字
    for (int i = 1; i <= 9; i++) {
        if (a[i] != 0) {
            printf("%d", i);
            a[i]--;
            break;
        }
    }

    // 输出其余数字
    for (int i = 0; i <= 9; i++) {
        for (int j = 0; j < a[i]; j++) {
            printf("%d", i);
        }
    }

    return 0;
}

C++实现:

#include <iostream>
using namespace std;
int main()
{
    int a[10];
    for (int i = 0; i <= 9; i++)
    {
        cin >> a[i];
    }
    for(int i=1;i<=9;i++){
        if(a[i]!=0){
            cout<<i;    //非a[i]
            a[i]--;
            break;
        }     
    }
    for(int i=0;i<=9;i++){
        for(int j=0;j<a[i];j++){
            cout<<i;
        }
    }
    return 0;
} 

6.字符串/指针初步

6.4说反话

        给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出。

        输入格式:测试输入包含一个测试用例,在一行内给出总长度不超过80的字符串。字符串由若干单词和若干空格组成,其中单词是由英文字母(大小写有区分)组成的字符串,单词之间用1个空格分开,输入保证句子末尾没有多余的空格。

        输出格式:每个测试用例的输出占一行,输出倒序后的句子。

        输入样例
Hello World Here I Come
        输出样例
Come I Here World Hello

C语言实现:

#include <stdio.h>
#include <string.h>

// 定义一个字符数组str,长度为81
char str[81];

int main()
{
    // 定义一个整数变量i,一个字符指针p
    int i, k;
    char *p;
    // 获取输入字符串
    gets(str);
    // 获取字符串长度
    k = strlen(str);
    // 获取字符串最后一个字符的地址
    p = str + k;
    // 循环判断
    while (1)
    {
        // 如果字符指针p指向字符串str的第一个字符,则退出循环
        if ( p == str )
        {
            printf("%s\n", p);
            break;
        }
        // 如果字符指针p指向的字符为空格,且下一个字符不为空格,则将p指向的字符置为空字符,并输出
        if (*p == ' ' && *(p+1) != ' ')
        {
            *p = '\0';
            printf("%s ", p+1);
        }
        // 字符指针p向前移动一位
        p--;
    }
    // 返回0
    return 0;
}

C++实现:

#include <iostream>
#include <cstring>
using namespace std;
// 定义一个字符数组str,长度为81
char str[81];
int main()
{
    // 定义一个整数变量i,一个字符指针p
    int k;
    char *p;
    // 获取输入字符串
    cin.getline(str, 81);
    // 获取字符串长度
    k = strlen(str);
    // 获取字符串最后一个字符的地址
    p = str + k;
    // 循环判断
    while (true)
    {
        // 如果字符指针p指向字符串str的第一个字符,则退出循环
        if (p == str)
        {
            cout << p << endl;
            break;
        }
        // 如果字符指针p指向的字符为空格,且下一个字符不为空格,则将p指向的字符置为空字符,并输出
        if (*p == ' ' && *(p + 1) != ' ')
        {
            *p = '\0';
            cout << p + 1 << " ";
        }
        // 字符指针p向前移动一位
        p--;
    }
    // 返回0
    return 0;
}

6.1在字符串中查找指定字符

        输入一个字符串S,再输入一个字符c,要求在字符串S中查找字符c。如果找不到则输出“Not found”;若找到则输出字符串S中从c开始的所有字符。

        输入格式:

输入在第1行中给出一个不超过80个字符长度的、以回车结束的非空字符串;在第2行中给出一个字符。

        输出格式:

在一行中按照题目要求输出结果。

        输入样例1:
It is a black box
b

        输出样例1:
black box
        输入样例2:
It is a black box
B

        输出样例2:
Not found

C语言实现:

 #include <stdio.h>
#include <string.h>

int main()
{
    int i, c;
    char str[81]; // 增加 1 个字符用于存储字符串结束符 '\0'
    
    gets(str);

    // 获取要查找的字符
    scanf("%d", &c);
    
    int m = strlen(str);
    int flag = -1;
    for (i = 0; i < m; i++)
    {
        if (str[i] == c)
            flag = 1;
        if (flag)
            printf("%c", str[i]);
    }
    if (flag != 1)
        printf("No found!\n");
    else
        printf("\n");

    return 0;
}

C++实现:

 #include <iostream>
#include <cstring>
using namespace std;
int main()
{
    int i, c;
    char str[81];
    gets(str);
    cin >> c;
    int m = strlen(str);
    int flag = -1;
    for (i = 0; i < m; i++)
    {
        if (str[i] == c)
            flag = 1;
        if (flag)
            cout << str[i];
    }
    if (flag != 1)
        cout << "No found!" << endl;
    else
        cout << endl;
}

6.2字符串逆序

        输入一个字符串,对该字符串进行逆序,输出逆序后的字符串。

        输入格式:

输入在一行中给出一个不超过80个字符长度的、以回车结束的非空字符串。

        输出格式:

在一行中输出逆序后的字符串。

        输入样例:
Hello World!
        输出样例:
!dlroW olleH

C语言实现:

#include <stdio.h>
#include <string.h>

int main() {
    int i, c;
    char str[81]; // 增加 1 个字符用于存储字符串结束符 '\0'
    
    gets(str);

    // 获取要查找的字符
    scanf("%d", &c);
    
    int m = strlen(str);
    int flag = -1;
    for (i = 0; i < m; i++) {
        if (str[i] == c)
            flag = 1;
        if (flag)
            printf("%c", str[i]);
    }
    if (flag != 1)
        printf("No found!\n");
    else
        printf("\n");

    return 0;
}

C++实现:

#include<iostream>
#include<cstring>
using namespace std;
int main(){
    int m;
    char str[81];
    gets(str);
    m=strlen(str)-1;
    for(;m>=0;m--)
        cout<<str[m];
    cout<<endl;
}

6.3字符串循环左移

输入一个字符串和一个非负整数N,要求将字符串循环左移N次。

        输入格式:

输入在第1行中给出一个不超过100个字符长度的、以回车结束的非空字符串;第2行给出非负整数N。

        输出格式:

在一行中输出循环左移N次后的字符串。

        输入样例:
Hello World!
2

        输出样例:
llo World!He

C语言实现:

#include <stdio.h>
#include <string.h>

int main() {
    char str[101];
    gets(str);
    int m = strlen(str);
    int x, flag = -1;
    cin >> x;
 // 第一次遍历:从前往后,把字符串中的字符复制到字符串的后面
    int i, j;
    for (i = 0; i < m; i++) {
        if (i == x)
            flag = 1;
        if (flag == 1) {
            for (j = 0; j < x; j++) {
                str[m + j] = str[j];
                flag = 0;
            }
        }
        if (flag == 0)
            str[i - x] = str[i];
        if (i >= m - x)
            str[i] = str[i + x];
    }
//第二遍遍历,循环输出
    for (i = 0; i < m; i++)
        printf("%c", str[i]);
    
    return 0;
}

C++试下:

#include <iostream>
using namespace std;
#include <cstring>
int main()
{
    char str[101];
    gets(str);
    int m = strlen(str);
    int x, flag = -1;
    cin >> x;
    int i, j;
    // 第一次遍历:从前往后,把字符串中的字符复制到字符串的后面
    for (i = 0; i < m; i++){
        if (i == x){
            flag = 1;
        }
        if (flag==1){
            for (j = 0; j < x ; j++){
                str[m + j] = str[j];
                flag = 0;
            }
        }
        if(flag==0){
            str[i-x]=str[i];  
        }
        if (i >= m - x ){
            str[i] = str[i+x];
        }
    }
    // 第二次遍历:从前往后,输出字符串
    for (i = 0; i < m; i++){
        cout << str[i];
    }
    return 0;
}

6.5删除特定字符串的字串

输入2个字符串S1和S2,要求删除字符串S1中出现的所有子串S2,即结果字符串中不能包含S2。

        输入格式:

输入在2行中分别给出不超过80个字符长度的、以回车结束的2个非空字符串,对应S1和S2。

        输出格式:

在一行中输出删除字符串S1中出现的所有子串S2后的结果字符串。

        输入样例:
Tomcat is a male ccatat
cat

        输出样例:
Tom is a male

C语言实现:

#include <stdio.h>
#include <string.h>

int main() {
    char str[81];
    char stri[10];

    gets(str);
    gets(stri);

    char *p = strstr(str, stri); // 查找子字符串的位置

    while (1) {
        if (p) {
            int i;
            // 计算要移除的字符数
            int remove_len = strlen(stri);
        
            // 将子字符串后面的字符向前移动
            for (i = 0; i < strlen(p) - remove_len; i++) {
                p[i] = p[remove_len + i];
            }
            p[i] = '\0'; // 添加字符串结束符
        } else {
            // 输出处理后的字符串
            printf("%s\n", str);
            break;
        }
        p = strstr(str, stri); // 继续查找下一个匹配的子字符串位置
    }

    return 0;
}

C++实现:

#include<iostream>
#include<cstring>
using namespace std;
int main(){
    // 输入字符串
    char str[81];
    char stri[10];
    gets(str);
    gets(stri);
    // 查找子串
	char *p = strstr(str, stri);
	while(1)
	{
        int i=0;
		// 查找子串,如果找到,则进行替换
		char *p = strstr(str, stri);
		if ( p )
		{
			// 遍历子串后面的字符,进行替换
			for ( i=0; i<strlen(p) - strlen(stri); i++ )
			{
				p[i] = p[strlen(stri) + i];
			}
			p[i] = '\0';
	    }
	    else
		{
	    	// 如果没有找到子串,则输出原字符串
	    	puts(str);
	    	// 结束程序
	    	break;
		}
	}
    return 0;
} 

        整完了,好好消化,去刷题吧!

        喜欢记得三连,持续更新C/C++相关内容,一起成长,共同进步!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值