C语言——字符串问题合集(1)

问题一:字符串反转


题目要求:

输入一个字符串(可包含任何非控制字符),对该字符串进行反转操作,
操作要求,只对字母进行反转,其他非字母字符都要求保留在原地。

输入格式:在一行输入长度不超过100的字符串
输出格式:在一行输出对字符串中字母进行反转操作后的字符串

输入样例1:

a-bC-d

输出样例1

d-Cb-a

输入样例2:

He llo+world!

输出样例2:

dl row+olleH!


解决思路:

 分别从两头出发,遍历整个字符串,如果两边都是英文,则交换,两边遇到不是英文的,就继续往下进行遍历。


 代码实现:

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

void invertstr(char *str);		//用于字符串转换 
int fun(char ch);				//用于判断是否为英文字符 

int main()
{
	char str[100];
	gets(str);
	
	invertstr(str);
	
	return 0;
}

void invertstr(char *str)
{
	int length,i,j;
	length = strlen(str);
	
	if(length <= 0)			//异常情况 
	{
		printf("empty");
		return ;
	}
	
	i = 0;					//两边出发 
	j = length - 1;
	while(i < j)
	{
		if((fun(str[i]) == 1) && (fun(str[j]) == 1))	//两边都是英文字符:交换后遍历 
		{
			char temp = str[i];
			str[i] = str[j];
			str[j] = temp;
			i++;
			j--; 
		}
		else if(fun(str[i] == 0) && fun(str[j]) == 0)	//两边都不是,继续往中间走 
		{
			i++;
			j--; 
		}
		else if(fun(str[i]) == 0)		//左边不是英文字符 
		{
			i++;
		}
		else
		{
			j--;
		}
	} 
	puts(str);
	
	return ; 
}

int fun(char str)
{
	if((str >= 'a' && str <= 'z') || (str >= 'A' && str <= 'Z'))
	{
		return 1;
	}
	else
	{
		return 0;
	}
}

 运行结果:


问题二:字符串子串查找(求出现次数)


题目要求:

 从键盘输入str1和str2两个字符串(长度小于20),求str2在str1中出现的次数
(注意考虑输入空格的情况)
注:禁止使用任何字符串处理函数

输入样例1:

          vjhdbhsvdkjsadvcsa
          sv

输出样例1:

                 1

输入样例2:

              asdcsa sdsdlajnvasd
              asd

输出样例2:

                2


解决思路:

        在原字符逐一遍历的情况下 ,同时遍历字符串,注意比较的时候,是要把逐一遍历的字符,串在一起,才能查找是否存在子字符串。然后相等的话就标志,最后符合相等的标志,就计数加一。


代码实现:

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

int find(char *str1,char *str2,int len_a,int len_t);

int main()
{
	char str1[20],str2[20];
	gets(str1);
	gets(str2);
	
	int len_a = strlen(str1);
	int len_t = strlen(str2);
	
	int cnt = find(str1,str2,len_a,len_t);
	printf("%d",cnt);
	
	return 0;
}


int find(char *str1,char *str2,int len_a,int len_t)
{
	int flag = 1;
	int cnt = 0;
	
	if(len_a <= 0 || len_t <= 0 || len_a - len_t <= 0)	//异常情况 
	{
		return 0;
	}
	
	for(int i = 0;i <= len_a - len_t;i++)		//从字符串里查找子串 
	{
		flag = 1;								//标志一下 
		for(int j = 0; j < len_t;j++)
		{
			if(str1[i+j] == str2[j])			//找到了 
			{
				flag = 1;
			}
			else
			{
				flag = 0;
				break;
			}
		}
		if(flag == 1)							//找到计数+1 
		{
			cnt++;
		} 
	}
	
	return cnt;
}


 运行结果:

 


 问题三:字符串子串查找(求子串下标)


题目要求:

实现功能:输入一个主字符串和一个子字符串,
在主字符串中找出子字符串出现的第一个位置 (从0开始)。

样例输入:

           hudhushfhwriohfids

           wrio

样例输出:

        9


解题思路:

        与问题二思路一直,要注意的是打印下标后的break,求的是子串第一个出现的位置。


 代码实现:

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

void find(char *str,char *str1,int len,int len1);

int main()
{
	char str[20],str1[20];
	int len,len1;
	
	gets(str);
	gets(str1);
	
	len = strlen(str);
	len1 = strlen(str1);
	
	
	find(str,str1,len,len1);
	
	return 0;
}

void find(char *str,char *str1,int len,int len1)
{
	int flag = 1;
	int j,i;
	
	if(len <= 0 || len1 <= 0 ||len - len1 <= 0)
	{
		printf("no find");
		return;
	}

	for(i = 0;i <= len - len1;i++)
	{
		for(j = 0;j < len1;j++)
		{
			if(str[i+j] == str1[j])
			{
				flag = 1;
			}
			else
			{
				flag = 0;
				break;
			}
		}
		if(flag == 1)
		{
			printf("%d",i);
			break;
		}		
	}
	return ;
} 

运行结果:


问题四:凯撒密码 


题目要求:

为了防止信息被别人轻易窃取,需要把电码明文通过加密方式变换成为密文。输入一个以回车符为结束标志的字符串(少于80个字符),再输入一个整数offset,用凯撒密码将其加密后输出。凯撒密码是一种简单的替换加密技术,将明文中的所有字母都在字母表上偏移offset位后被替换成密文,当offset大于零时,表示向后偏移;当offset小于零时,表示向前偏移。

输入格式:

输入第一行给出一个以回车结束的非空字符串(少于80个字符);第二行输入一个整数offset。

输出格式:

输出加密后的结果字符串。

输入样例1:

Hello Hangzhou

2

输出样例1:

Jgnnq Jcpibjqw 

输入样例2:

                a=x+y
                -1

输出样例2:

               z=w+x 


 解决思路:

  1. 遍历字符串,先判断字符串本身是否在“A~Z”or"a~z";
  2. 再判断加上offset是否还在英文字符内,如果在直接加上offset;
  3. 如果不在,分两种情况:①如果比“a” or “A”小,那就加上offset后加上26(英文字母个数);②如果比“z” or "Z"大,就加上offset后再减去26;
  4. 输出操作之后的字符串即可

注意:对于输入的offset要和26做先取余的处理。


代码实现:

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

int main()
{
	char str[81];
	gets(str);
	
	int offset;
	scanf("%d",&offset);
	
	offset %= 26;			//先处理offset 
	
	for(int i = 0;i < strlen(str);i++)		//遍历字符串 
	{
		if(str[i] >= 'A' && str[i] <= 'Z')
		{
			if(str[i] + offset >= 'A' && str[i] + offset <= 'Z')
			{
				str[i] += offset;
			}
			else if(str[i] + offset > 'Z')
			{
				str[i] = str[i] + offset - 26;
			}
			else if(str[i] +offset < 'A')
			{
				str[i] = str[i] + offset + 26;
			}
		 } 
		 
		 if(str[i] >= 'a' && str[i] <= 'z')
		 {
		 	if(str[i] + offset >= 'a' && str[i] + offset <= 'z')
		 	{
		 		str[i] += offset;
			}
			else if(str[i] + offset < 'a')
			{
				str[i] = str[i] + offset + 26; 
			}
			else if(str[i] + offset > 'z')
			{
				str[i] = str[i] + offset - 26;
			}
		 }
	}
	
	printf("%s",str);
	
	return 0;
}

运行结果:


问题五:字符串排序去重(含非常规字符)


题目要求:

要求编写程序,将给定字符串去掉重复的字符后,按照字符ASCII码顺序从小到大排序后输出

(注意:给定字符可能是非常规字符)

输入格式:

输入是一个以回车结束的非空字符串(少于80个字符)。

输出格式:

输出去重排序后的结果字符串。

输入样例:

ad2f3ad j feain  zzzv

输出样例:

 


解题思路:

先把字符串排序,然后打印时候在进行去重操作,注意输入的用gets,可能含有非常规字符 


代码实现:

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

int main()
{
	char str[81];
	gets(str);
	
	int length = strlen(str);
	
	for(int i = 0;i < length - 1;i++)			//先把字符串排序 
	{
		for(int j = 0;j < length - 1 - i;j++)
		{
			if(str[j] > str[j+1])
			{
				char temp = str[j];
				str[j] = str[j+1];
				str[j+1] = temp;
			}
		}
	}
	
	for(int i = 0;i < length;i++)
	{
		if(str[i] != str[i+1])			//打印时候去重 
		{
			printf("%c",str[i]); 
		}
	}
	return 0;
} 

运行结果:


问题六:字符串排序(字符数组)


题目要求:

本题要求编写程序,读入n个字符串,按由小到大的顺序输出。

输入格式:

先输入一个数字n,再输入由空格分隔的n个非空字符串,每个字符串不包括空格、制表符、换行符等空白字符,长度小于80。

输出格式:

按照以下格式输出排序后的结果:

After sorted:

每行一个字符串

输入样例:

5

red yellow blue black white

结尾无空行

输出样例:

After sorted:

black

blue

red

white

yellow

结尾无空行


解题思路:

  1.  首先,因为要排序的是英文单词,每一行有n个字母,所以我们应该想到要定义一个字符数组;
  2. 输入每行的字符串(英文单词),然后进行字符串排序(可以用字符串函数)
  3. 输出排序后结果

代码实现:

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

int main()
{
	int n;
	scanf("%d",&n);
	
	char str[n][81];
	int i,j;
	for(i = 0;i < n;i++)
	{
		scanf("%s",str[i]);		//注意输入的是"行",是字符串,用%s 
	}
	
	char temp[n];	//用于字符串排序交换
	for(i = 0;i < n - 1;i++)                //冒泡排序
	{
		for(j = 0;j < n - 1 - i;j++)
		{
			if(strcmp(str[j],str[j+1]) > 0)
			{
				strcpy(temp,str[j]);
				strcpy(str[j],str[j+1]);
				strcpy(str[j+1],temp); 
			}
		}
	} 
	 
	printf("After sorted:\n");
	for(i = 0;i < n-1;i++)			//最后一个单独输出,保证结尾无空行 
	{
	 	printf("%s\n",str[i]);		//输出字符串 
	}
	printf("%s",str[n-1]);
	
	return 0;
	 
}

运行结果:


问题七:统计一行文本的单词个数


题目要求:

本题目要求编写程序统计一行字符中单词的个数。所谓“单词”是指连续不含空格的字符串,各单词之间用空格分隔,空格数可以是多个。

输入格式:

输入给出一行字符。

输出格式:

在一行中输出单词个数。

 输入样例:

Let's go to room 209.

输出样例:


解题思路:

此题要注意的点,在于如何定义是一个单词,注意单词前后的特点,如果符合,单词个数计数加一。


代码实现:

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

int main()
{
	char str[100];
	gets(str);
	
	int len = strlen(str);
	int i,cnt = 0;
	
	for(i = 0;i < len;i++)
	{
		if(str[i] != ' ' && str[i+1] == ' ')	//如果下一个是空格 就算一个单词 
		{
			cnt++;
		}
		if(str[i] != ' ' && str[i+1] == '\0')	//如果下一个就是字符串结束符,也算一个单词 
		{
			cnt++;
		}
	}
	
	printf("%d",cnt);
	return 0;
} 
 

运行结果:


问题八:寻找最长字符串(字符数组)


题目要求:

本题要求编写程序,针对输入的N个字符串,输出其中最长的字符串。

输入格式:

输入第一行给出正整数N;随后N行,每行给出一个长度小于80的非空字符串,其中不会出现换行符,空格,制表符。

输出格式:

在一行中用以下格式输出最长的字符串:

The longest is: 最长的字符串

提示:如果字符串的长度相同,则输出先输入的字符串。 

输入样例 

5
li
wang
zhang
jin
xiang

输出样例:

The longest is: zhang


解题思路:

此题考察的是字符数字的运用,一行给出字符串,然后进行遍历,比较每一次遍历的字符串是否比前面长,如果长则赋值给前面,一直查找,直到遍历结束。


代码实现:

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

int main()
{
	int n;
	scanf("%d",&n);
	
	char str[n][100];
	int i;
	for(i = 0;i < n;i++)
	{
		scanf("%s",str[i]);		//每行输入字符串 
	}
	
	int max = 0,j;			//记录最长
	for(i = 0;i < n ;i++)
	{
		if(strlen(str[i]) > max)		//遍历,每次进行比较 
		{
			max = strlen(str[i]);		// 如果大,就赋值 
			j = i;						//直到找到最大的,下标交出去 
		}
	}
	
	printf("The longest is: %s",str[j]);
	return 0; 
 } 

运行结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值