字符串的转换、逆置、删除重复元素及判断是否为邮件格式

1.给定的一个字符串,比如:this is my program,要求将每个单词的首字母大写,输出:This Is My Program 。

#include <stdio.h>

int getsline(char *s)
{
	int i = 0, c;
	if(s == NULL)
		return 0;
	for(i = 0; (c = getchar()) != EOF && c != '\n'; ++i)
		s[i] = c;
	s[i] = '\0';
	return i;
}

//思路比较简单,代码比较容易理解
//将字符串每个单词的首字母转化为大写
char* ConvertFirstUpper(char *word)
{
	int isalph = 1;
	if(word == NULL)
		return NULL;

	char *p = word;
	while(*p != '\0')
	{
		//找到单词首字母并转换
		if(isalph == 1 && (*p >= 'a' && *p <= 'z'))
		{
			isalph = 0;
			*p = *p - 32;
		}
		else if(isalph == 0 && *p == ' ')
		{
			isalph = 1;
		}
		++p;
	}
	//返回处理后的字符串
	return word;
}

int main()
{
	char str[100];
	while(getsline(str))
	{
		ConvertFirstUpper(str);
		puts(str);
	}
	return 0;
}

2.给定一个字符串,要求将其逆向输出,如:adcdefgik,输出:kigfedcda 。

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

//逆转字符串
char* Reverse(char *word)
{
	int len = 0;
	char *be, *end;
	if(word == NULL)
		return NULL;
	be = word;
	end = word + strlen(word) - 1;
	while(be < end)
	{
		char temp = *be;
		*be = *end;
		*end = temp;
		++be; --end;
	}
	return word;
}

int main()
{
	char word[] = "abcdefg";
	Reverse(word);
	printf("%s\n", word);
	return 0;
}

3.给定一个字符串,要求删掉重复的字符,只保留其中一个。如:aabcdddffgh,输出:abcdfgh 。

#include <stdio.h>

//利用Hash思想,设数组table表示字符是否存在于字符串中
//第一次遍历字符串,设置字符出现标志为1
//第二次遍历字符串,如果相应的字符在table中的标识为1,
//则打印该字符并设置table中的标识为0,否则不作处理
//将最终处理结果保存至newword字符串
void DeleteReWord(char word[], char newword[])
{
	//0~25标识a~z,26~51标识A~Z
	int table[52] = {0};
	char *p = word;
	if(word == NULL || newword == NULL)
		return;
	//第一次遍历字符串
	while(*p != '\0')
	{
		if(*p >= 'a' && *p <= 'z')
			table[*p - 'a'] = 1;
		else if(*p >= 'A' && *p <= 'Z')
			table[*p - 'A' + 26] = 1;
		++p;
	}
	p = word;
	//第二次遍历字符串
	while(*p != '\0')
	{
		if(*p >= 'a' && *p <= 'z' && table[*p - 'a'] == 1)
		{
				*newword = *p;
				newword++;
				table[*p - 'a'] = 0;
		}
		else if(*p >= 'A' && *p <= 'Z' && table[*p - 'A' + 26] == 1)
		{
			*newword = *p;
			newword++;
			table[*p - 'A' + 26] = 0;
		}
		++p;
	}
	*newword = '\0';
}

int main()
{
	char word[100], newword[100];
	scanf("%s", word);
	DeleteReWord(word, newword);
	printf("%s\n%s\n", word, newword);
	return 0;
}

4.给定一个字符串,让你判定是否是正确的邮件地址。

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

//KMP算法求子串在主串中的位置
int next[100];
void getnext(char *str)
{
	int i = 1, j = 0;
	next[1] = 0;
	while(i <= strlen(str))
	{
		if(j == 0 || str[i - 1] == str[j - 1])
		{
			i++;  j++;
			next[i] = j;
		}
		else
		{	
			j = next[j];
		}
	}
}

int kmp(char *a, char *b)
{
	int i = 1, j = 1; //i是主串中的位子 ,j匹配串的位子
	while(i <= strlen(a) && j <= strlen(b))
	{
		if(j == 0 || a[i - 1] == b[j - 1])
		{
			i++; j++;
		}
		else 
			j = next[j];
	}
	if(j > strlen(b))
		return i - strlen(b);
	else
		return 0;
}

//合法的email地址格式如下:
//1. 首字符必须用字母,而且其它的字符只能用26个大小写字母、0~9及_-.@符号后的
//2. 必须包含一个并且只有一个符号“@”
//3. @后必须包含至少一个至多三个符号“.”
//4. 第一个字符不得是“@”或者“.”(第一步已检查过了)
//5. 不允许出现“@.”或者.@
//6. 结尾不得是字符“@”或者“.”
int isvalidchar(char ch)
{
	if((ch >= 97) && (ch <= 122) ) //26个小写字母
		return 1;
	if((ch >= 65) && (ch <= 90) ) //26个大写字母
		return 1;
	if((ch >= 48) && (ch <= 57)) //0~9
		return 1;
	if(ch == 95 || ch == 45 || ch == 46 || ch == 64 ) //_-.@
		return 1;
	return 0;
}

//判定输入的字符串是否是正确的邮件地址,如果是返回1,否则返回0
int isvalidemail(char *email)
{
	int i = 0;
	if(email == NULL)
		return 0;

	if(strlen(email) < 5) //26个小写字母
		return 0;

	char ch = email[0];
	if(((ch >= 97) && (ch <= 122)) || ((ch >= 65) && (ch <= 90)))
	{
		int atcount =0;  //"@"的个数
		int atpos = 0;   //"@"所在的位置
		int dotcount = 0; //"."的个数
		for(i = 1; i < strlen(email); i++) //0已经判断过了,从1开始
		{
			ch = email[i];
			if(isvalidchar(ch))
			{
				if(ch == 64) //"@"
				{
					atcount++;
					atpos = i;
				}
				else if(atcount > 0 && ch == 46)//@符号后的"."号
					dotcount++;
			}
			else
				return 0;
		}
		//结尾不得是字符“@”或者“.”
		if(ch == 46)
			return 0;
		//必须包含一个并且只有一个符号“@”
		//@后必须包含至少一个至多三个符号“.”
		if((atcount != 1) || (dotcount < 1) || (dotcount > 3))
			return 0;
		//不允许出现“@.”或者.@
		int x, y;
		x = kmp(email, "@.");
		y = kmp(email, ".@");
		if(x > 0 || y > 0)
			return 0;
		
		return 1;
	}
	return 0;
}

//接收一行字符(最多num个),使用gets易出现缓冲区溢出
int getsline(char s[], int num)
{
	int i, c;
	for(i = 0; i < num - 1 && (c = getchar()) != EOF && c != '\n'; ++i)
		s[i] = c;
	s[i] = '\0';
	return i;
}

int main()
{
	char str[100];
	while(1)
	{
		getsline(str, 100);
		if(isvalidemail(str) == 1)
			puts("valid email");
		else
			puts("invalid email");
	}
	return 0;
}


对于上述题目如果有更好的算法或改进建议,欢迎留言交流。


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值