文章目录
- NO1、选出妃子、宫女和嬷嬷
- No2、根据数字判断月份
- No3、循环计数
- No4、循环选数
- No5、玩转字符
- No6、计算字符串长度
- No7、显示字符串中的字符
- No8、字符串反转
- No9、二维数组的应用
- No10、整数转化字符串课后
- No11、把字符串转化为整数
- No12、实现strcpy和strncpy函数
- No13、实现strcat和strncat函数
- No14、实现strchr和strrchr函数
- No15、实现strcmp和strncmp函数
- No16、实现strstr函数 复刷
- No17、删除字符串右边指定的字符 复刷
- No18、删除字符串左边指定的字符 复刷
- No19、删除字符串中间指定的字符 复刷
- NO20、统计字符串的字数 复刷
- NO21、拆分字符串 复刷
- NO22、解析XML字符串
- NO23、随机数
- NO24、随机发牌
NO1、选出妃子、宫女和嬷嬷
其他要求:
- 超女用结构体表示
- 不要嵌套if
- 输入所有数据后再判断
#include <iostream>
#include <string>
using namespace std;
struct CGirl {
int age;
int high;
string sc;
//c风格字符串 char sc[31]; 字符串比较就要用 strcmp
bool yz;
};
int main() {
CGirl g;
cout << "请依次输入年龄、身高(cm)、身材(火辣/普通)、颜值(漂亮/一般):";
string stringYz{0};
cin >> g.age >> g.high >> g.sc >> stringYz;
g.yz = (stringYz == "漂亮") ? true : false;
if ((g.age >= 18 && g.age <= 25) && (g.high >= 165 && g.high <= 178) && (g.sc == "火辣") && g.yz)
cout << "妃子" << endl;
else if ((g.age >= 18 && g.age <= 30) && (g.high >= 160 && g.high < 165) && (g.sc == "火辣" || g.sc == "普通") &&
g.yz)
cout << "宫女" << endl;
else if ((g.age >= 35 && g.age <= 40) && (g.high >= 155 && g.high < 165) && (g.sc == "飞机场" || g.sc == "普通") &&
(!g.yz))
cout << "嬷嬷" << endl;
/* else
cout<<"落选"<<endl;*/
return 0;
}
No2、根据数字判断月份
其他要求:
- ifelse或者switchcase实现
- 字符串数组实现(C/C++)
#include <iostream>
int main() {
int mouth = -1;
std::cout << "请输入月份(1-12):";
std::cin >> mouth;
/*switch (mouth) {
case 1:
std::cout<<"January"<<std::endl;
break;
case 2:
std::cout<<"February"<<std::endl;
break;
case 3:
std::cout<<"March"<<std::endl;
break;
case 4:
std::cout<<"April"<<std::endl;
break;
case 5:
std::cout<<"May"<<std::endl;
break;
case 6:
std::cout<<"June"<<std::endl;
break;
case 7:
std::cout<<"July"<<std::endl;
break;
case 8:
std::cout<<"August"<<std::endl;
break;
case 9:
std::cout<<"September"<<std::endl;
break;
case 10:
std::cout<<"October"<<std::endl;
break;
case 11:
std::cout<<"November"<<std::endl;
break;
case 12:
std::cout<<"December"<<std::endl;
break;
default:
std::cout<<"输入错误"<<std::endl;
}*/
//效率高于ifelse 和 switch case
char months[12][10] = {"January","February","March","April","May","June","July"
,"August","September","October","November","December"};
if (mouth>=1&&mouth<=12)
std::cout<<months[mouth-1]<<std::endl;
else
std::cout<<"输出错误"<<std::endl;
}
No3、循环计数
#include <iostream>
int main() {
int sum = 0;
int i = 0;
while (i <= 100) {
sum += i++;
}
std::cout << "1-100之间的和为" << sum << "\n";
int num{0};
int sumF{0};;
for (;sumF <= 5000;) {
std::cin>>num;
sumF+=num;
}
std::cout << "输入的和为" << sumF << "\n";
return 0;
}
No4、循环选数
/**
******************************************************************************
* @file : demo4.cpp
* @author : DELL
* @brief : None
* @attention : None
* @date : 2024-01-25
******************************************************************************
*/
#include <iostream>
int main() {
int num{0}, count{0}, sum{0};
while (std::cin >> num) {
if (!num)break;
if (num < 1 || num > 100)
continue;
count++;
sum += num;
}
std::cout << "符合条件个数:" << count << "--" << "它们的和:" << sum << "\n";
int n{1};
//取余数
while (n <= 100) {
if (n % 5 == 0)
std::cout << n << " ";
++n;
}
std::cout << "\n";
//另外一种写法
n = 5;
while (n <= 100) {
std::cout << n << " ";
n += 5;
}
return 0;
}
No5、玩转字符
//ASCII A->65 Z->90 a->97 z->122
void printLastChar(char &&c) {
if (!((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))) {
std::cout << "输入不合规" << "\n";
return;
}
if (c == 'Z' || c == 'z') {
std::cout << c << "的后面没有字符" << "\n";
return;
}
std::cout << c << "后面的字符是:" << char(c + 1) << std::endl;
}
int ctoi(const char ch) {
if (ch < '0' || ch > '9') {
std::cout << "参数不合规" << std::endl;
return -1;
}
return int(ch - 48);
}
No6、计算字符串长度
其他要求
- 封装成一个函数
- for循环+数组表示法+临时变量
- while+指针表示+临时变量
- 不用临时变量->递归
int len(char *c) {
//1、for循环+临时变量+数组表示法
/*int len{0};
for (; c[len] != '\0'; ++len);
return len;*/
//2、while循环+临时变量+指针表示法
/*char *p = c;
int len{0};
while (*p++)
++len;
return len;*/
//3、递归思路+不采用临时变量
//递归开销大于循环)(
if (*c == '\0')return 0;//中止条件
c++;//指针后移
return len(c) + 1;//后移之后的长度+1=本来的长度
//递归中我们可以把下一层当作已知参数,比如
}
No7、显示字符串中的字符
void printStr(const char *c, bool isSequence = true) {
int len = strlen(c);
if (isSequence) {
for (int i = 0; i < len; ++i) {
std::cout << c[i] << " ";
}
} else {
for (int i = len - 1; i >= 0; --i) {
std::cout << c[i] << " ";
}
}
std::cout << std::endl;
}
No8、字符串反转
//使用另外一个字符串
char *reverse(const char *str){
char *newStr = new char[30];
int len = ::strlen(str);
::memset(newStr,0, sizeof(newStr));
for (int i = 0,j=len-1; i < len;)
newStr[i++] = str[j--];
return newStr;
}
//原地反转
void reserveS(char *str){
//abc d
int len = ::strlen(str);
int n = len/2;
for (int i = 0; i < n; ++i) {
char tmp = str[i];
str[i] = str[len-i-1];
str[len-i-1] = tmp;
}
}
No9、二维数组的应用
任务一
double weights[3][4];
::memset(weights,0, sizeof(weights));
double total{0};
for (int i = 0; i < 3; ++i) {
double sum{0};
for (int j = 0; j < 4; ++j) {
double weight{0};
cout<<"请输入第"<<i+1<<"组第"<<j+1<<"个超女的体重:";
cin>>weight;
weights[i][j] = weight;
sum+=weight;
}
total+= sum;
cout<<"第"<<i+1<<"小组超女的平均体重:"<<sum/4<<"\n";
}
cout<<"所有小组超女的平均体重:"<<total/12<<endl;
任务二
char names[3][11];
::memset(names,0, sizeof(names));
for (int i = 0; i < 3; ++i) {
cout<<"请输入超女姓名:";
cin>>names[i];
}
for (int i = 0; i < 3; ++i) {
cout<<"表白:"<<names[i]<<"\n";
}
No10、整数转化字符串课后
/**
******************************************************************************
* @file : demo10.cpp
* @author : DELL
* @brief : None
* @attention : None
* @date : 2024-01-25
******************************************************************************
*/
#include <iostream>
using namespace std;
//可以将字符串反转 这样才是真正的
int main() {
cout << "请输入一个整数:";
int num{0};
char cNum[21];
cin >> num;
int index = 0;
int cnum{num};
//转化十进制
while (cnum) {
int tmp = cnum % 10;
cNum[index++] = static_cast<char>(tmp + 48);
cnum /= 10;
}
for (int i = index - 1; i >= 0; --i) {
cout << cNum[i];
}
cout << "\n";
//转化为二进制
index = 0;
cnum = num;
while (cnum) {
int tmp = cnum % 2;
cNum[index++] = static_cast<char>(tmp + 48);
cnum /= 2;
}
for (int i = index - 1; i >= 0; --i) {
cout << cNum[i];
}
return 0;
}
No11、把字符串转化为整数
补充:
可以选择二进制或者十进制 默认为十进制
int myAtoi(const char*s,int radix = 10){
int sum{0},len = ::strlen(s);
for (int i = 0; i < len; ++i) {
if (radix==10&&(*(s+i)>'9'||*(s+i)<'0'))return sum;
if (radix==2&&(*(s+i)>'1'||*(s+i)<'0'))return sum;
sum = sum*radix + *(s+i) - '0';
}
return sum;
}
No12、实现strcpy和strncpy函数
字符串赋值
#include <iostream>
using namespace std;
//数组表示法||还可以指针表示法
char *strcpy1(char *dest, const char *src) {
int i{0};
while (src[i]) {
dest[i] = src[i];
++i;
}
dest[i] = 0;//循环结束在目标字符串的结尾加上0
return dest;
}
//一次复制一整块内存
char *strcpy2(char *dest, const char *src) {
memcpy(dest, src, sizeof(src) + 1);//char是1B,+1是结尾标志0也要复制进去
return dest;
}
//时间消耗:复制一整块内存<指针<数组
char *strncpy(char *dest, const char *src,size_t n) {
memcpy(dest, src, n);
*(dest+n) = 0;//实际的strncpy是没有这一行的 所以会有bug
return dest;
}
#include <chrono>
int main() {
chrono::steady_clock::time_point start,end;
char dest[11], src[11]{"aasdcas"};
start = chrono::steady_clock::now();
for (int i = 0; i < 100000; ++i)
strcpy1(dest, src);
end=chrono::steady_clock::now();
cout<<"数组表示法时间:"<<static_cast<double>((end-start).count())/(1000*1000)<<"毫秒"<<endl;
start = chrono::steady_clock::now();
for (int i = 0; i < 100000; ++i)
strcpy2(dest, src);
end=chrono::steady_clock::now();
cout<<"复制整个内存时间:"<<static_cast<double>((end-start).count())/(1000*1000)<<"毫秒"<<endl;
return 0;
}
No13、实现strcat和strncat函数
拼接字符串
#include <iostream>
#include<cstring>
using namespace std;
char *m_strcat(char *dest, const char *src) {
size_t dLen = strlen(dest), sLen = ::strlen(src);
::memcpy(dest + dLen, src, sLen + 1);
return dest;
}
char *m_strncat(char *dest, const char *src, const size_t n) {
size_t len = strlen(dest);
::memcpy(dest + len, src, n);
*(dest + len + n) = 0;
return dest;
}
int main() {
char d[21] = "dududuying";
cout << m_strcat(d, "seu")<<"\n";
cout << m_strncat(d, "seuduseu",5)<<"\n";
return 0;
}
No14、实现strchr和strrchr函数
查找字符位置,返回的是地址
#include<iostream>
using namespace std;
const char *strchr(const char *s, char c) {
char *p = const_cast<char *>(s);
while (*p) {
if (c == *p)return p;
++p;
}
return nullptr;
}
const char *strrchr(const char*s,int c){
char *p=const_cast<char*>(s);
char*p1= nullptr;
while (*p){
if (*p == c)p1=p;
++p;
}
return p1;
}
int main() {
char s[21]{"abcdefgacaaacccadac"};
cout<<strchr(s,'a')<<endl;
cout<<strrchr(s,'a')<<endl;
return 0;
}
No15、实现strcmp和strncmp函数
比较str的大小
#include<iostream>
using namespace std;
int strcmp(const char*str1,const char*str2){
int i{0};
while (true){
if (str1[i]>str2[i])return 1;
if (str1[i]<str2[i])return -1;
if (str1[i]==0&&str2[i]==0)return 0;
++i;
}
}
int strncmp(const char*str1,const char*str2,size_t n){
for (int i = 0; i < n; ++i) {
if (str1[i]>str2[i])return 1;
if(str1[i]<str2[i])return -1;
// if (str1[i]==0&&str2[i]==0)return 0;
}
return 0;
}
int main(){
char s1[11]="abcde";
char s2[11]="abcde";
cout<<strcmp(s1,s2)<<endl;
cout<<strncmp(s1,s2,6)<<endl;
return 0;
}
No16、实现strstr函数 复刷
返回子串在目标串中第一次出现的位置
/*!
* 查找子串
* 两种方法:
* 1.BP 暴力算法 本次实现的是BP
* 2.KMP算法
*/
#include<iostream>
#include<cstring>
using namespace std;
//BP
const char *strstr_BP(const char *str, const char *substr) {
size_t i{0}, j{0}, len{::strlen(str)}, slen{::strlen(substr)};
while (i<len && j<slen){//i==len代表目标串结束 j==slen代表查找成功
if(str[i]==substr[j]){//如果比较相等,那么继续向后比较
++i;
++j;
} else{//如果比较不相等
i -=j;//目标串回退j位,回到本次起始的位置
j=0;//子串数组下标归0
++i;//目标串向后移1个字符(下次起始位置) 准备重来
}
}
//循环完 如果访问完毕了子串 说明成功
//但是此时i在目标串的末尾 j在子串末尾 所以子串在目标串匹配的位置如下
if(j==slen)return str+i-j;
return nullptr;//找不到返回空
}
int main() {
char str[21]="hxxhelloxadsad";
char substr[6]="hello";
cout<<strstr_BP(str,substr);
return 0;
}
No17、删除字符串右边指定的字符 复刷
#include<iostream>
#include<cstring>
using namespace std;
/*实例 删除y
* duyy -> du
* duyingyyy->duying
* */
void deleteChrR(char *str, const char c = ' ') {
if (str == nullptr)return;
char *p = str;//指向字符串首地址
char *piscc{nullptr};//指向右边全是字符c的第一个位置
while (*p) {
if (*p == c && piscc == nullptr)piscc = p;//记下字符c的第一个位置
if (*p!=c)piscc = nullptr;//只要当前字符不是c就清空piscc
++p;//最后在让p向后移动一个位置
}
if (piscc != nullptr)*piscc = 0;//遍历完成后,只要piscc不为空说明指向右边全是字符c的第一个位置存在
}
int main() {
char s[11] = "ada ss";
deleteChrR(s, 's');
cout << s << endl;
return 0;
}
No18、删除字符串左边指定的字符 复刷
#include<iostream>
#include<cstring>
using namespace std;
/* 删除y
* yydu -> du
* yyyduying->duying
* */
//传入的s是首地址 在函数改变str也改变不了传入s的首地址 str是s的复制
void deleteChrL(char *str, const char c = ' ') {
if(str== nullptr)return;
char*p{str};
while (*p==c){
++p;
}
::memmove(str,p, ::strlen(str)-(p-str)+1);
// ::memcpy(str,p, ::strlen(str)-(p-str)+1); 不可以
//原因:
//memcpy没有考虑内存重叠的情况,如果有内存重叠,他的行为是不确定的
//memmove()函数在memcpy()函数的基础上加入了对内存重叠拷贝的处理,保证其正确性。
//如果能确定拷贝内存没有重叠,memcpy()比memmove()更高效,如果有重叠,只能memmove
}
int main() {
char s[21] = "sssasda ss";
deleteChrL(s, 's');
cout << s << endl;
return 0;
}
No19、删除字符串中间指定的字符 复刷
实例:
目标字符:aaxxyzyzooo
删除字符:xyz
aaxxyzyzooo->aaxyzooo->aaooo
//可采用循环 或者 递归
//不要写无用代码
#include<iostream>
#include <cstring>
using namespace std;
char*strstr_BP(char *str,const char *substr){
int i{0},j{0};
size_t len = strlen(str),slen=strlen(substr);
while (i<len&&j<slen){
if(str[i]==substr[j]){
++i;
++j;
}else{
i-=j;
j=0;
++i;
}
}
if(j==slen)return str+i-j;
return nullptr;
}
void deleteStr(char*str,const char *substr){
if(str== nullptr||substr== nullptr)return;
while (true){
//里面的顺序是有讲究的
int slen = ::strlen(substr);
if(slen==0)return;
char *p = strstr_BP(str,substr);
if(p== nullptr)return;
size_t len= ::strlen(str);
::memmove(p,p+slen,len-(p-str)-slen+1);//+1是为了把结束符0移动过去
}
}
int main(){
char s[21]="aaxxyzyzooo";
deleteStr(s,"xyz");
cout<<s<<endl;
return 0;
}
NO20、统计字符串的字数 复刷
//clion的汉字占用三个字节
#include<iostream>
using namespace std;
int sumwords(const char *str){
int sum{0};
int flag{0};//记录是否为汉字 false:没有记录半个汉字 true:当前已经记录半个汉字
char* p= (char*)str;
while (*p){
if((unsigned char)*p<128){//ASCII码的标准字符
++sum;
} else{
if(flag==2){
++sum;
flag=0;
}else {
flag++;
}
}
p++;
}
return sum;
}
int main(){
char s[21]="你好的,?xxx";
cout<<sumwords(s)<<endl;
return 0;
}
NO21、拆分字符串 复刷
/**
******************************************************************************
* @file : 拆分字符串
* @author : DELL
* @brief : None
* @attention : None
* @date : 2024-01-30
******************************************************************************
*/
#include<iostream>
#include<cstring>
using namespace std;
/*!
* @param str 待拆分的字符串
* @param splitstr 数据项的分隔字符串
* @param value 存放拆分之后的值的数组
* @return 拆分后数据项的个数
*/
size_t splitstr(const char *str,const char *splitstr,char values[][51]){
if(str== nullptr||splitstr== nullptr)return 0;
size_t slen = ::strlen(splitstr);
if(slen==0)return 0;
char*p=const_cast<char *>(str);
int index{0};
while (true){
char*p1 = ::strstr(p,splitstr);
if(p1== nullptr){
::strcpy(values[index++],p);
break;
} else{
::strncpy(values[index++],p,p1-p);
p = p1 + slen;
}
}
return index;
}
int main(){
char s[11] = {"aa,cc,bb"};
char splits[5] = ",";
char values[10][51]={0};
size_t t = splitstr(s,splits,values);
for (size_t i = 0; i < t; ++i) {
cout<<values[i]<<endl;
}
cout<<t<<endl;
return 0;
}
NO22、解析XML字符串
NO23、随机数
/**
******************************************************************************
* @file : 随机数
* @author : DELL
* @brief : None
* @attention : None
* @date : 2024-01-30
******************************************************************************
*/
#include<iostream>
using namespace std;
//随机数在[minValue,minValue+len)
void rrand(int arr[],const size_t len,const int minValue = 0){
srand(time(nullptr));
for (int i = 0; i < len; ++i) {
while(true){
int tmp = rand()%len+minValue;
int j;
for (j=0; j < i; ++j)
if(tmp == arr[j])
break;
if(i==j){
arr[i]=tmp;
break;
}
}
}
}
int main(){
int arr[10]={0};
rrand(arr,5,10);
for (int i = 0; i <5 ; ++i) {
cout<< arr[i] <<endl;
}
return 0;
}
NO24、随机发牌
/**
******************************************************************************
* @file : 随机发牌
* @author : DELL
* @brief : None
* @attention : None
* @date : 2024-01-30
******************************************************************************
*/
//重点是一个发牌数组 一个洗牌数组 按照对应来发牌即可
#include<iostream>
using namespace std;
void rrand(int arr[], const int min, const int len) {
for (int i = 0; i < len; ++i) {
::srand(time(nullptr));
while (true) {
int j, tmp = rand() % len + min;
for (j = 0; j < i; ++j)
if (tmp == arr[j])break;
if (i == j) {
arr[i] = tmp;
break;
}
}
}
}
void dealCards(int arr[4][13]) {
int cards[52] = {-1};//洗牌数组,存放牌的数组
rrand(cards, 1, 52);
int sendCardsArr[52] = {-1};//发牌数组,存放所发牌的下标
rrand(sendCardsArr, 0, 52);
int j = 0;
for (int i = 0; i < 13; ++i) {
arr[0][i] = cards[sendCardsArr[j++]];
arr[1][i] = cards[sendCardsArr[j++]];
arr[2][i] = cards[sendCardsArr[j++]];
arr[3][i] = cards[sendCardsArr[j++]];
}
}
int main() {
int arr[4][13] = {0};
dealCards(arr);
for (int i = 0; i < 4; ++i) {
cout<< "玩家" <<i+1<<":";
for (int j = 0; j < 13; ++j) {
cout<<arr[i][j]<<" ";
}
cout<<"\n";
}
return 0;
}