char a[]=”abc";char b[]={‘a','b','c'};
char *c=”abc”;char *d=”abc”;
d与c指向同一个地址,c的内容修改后,指向发生改变,d的内容不更改
getchar----输入缓冲区------键盘,:
字符:#abc,字母A-Z
有符号、无符号只限于整形,
scanf函数返回成功读入的数据项数,读入数据时遇到了“文件结束”则返回EOF:
while (EOF != scanf("%d %d", &a, &b))
{
printf("%d %d\n", a, b);
}
int a=0,b=0;
printf("%d %d\n", scanf("%d %d", &a, &b));
函数返回值为int型。如果a和b都被成功读入,那么scanf的返回值就是2;
如果只有a被成功读入,返回值为1;如果a和b都未被成功读入,返回值为0;
如果遇到错误或遇到end of file,返回值为EOF=-1。end of file为Ctrl+z 或者Ctrl+d。
字符0=‘0’是48;’\0’:数值上就是0,在类型上,字符;空格的ASCII码值=32;
对于字符串数组或字符串指针变量,由于数组名可以转换为数组和指针变量名本身就是地址,因此使用scanf()函数时,不需要在它们前面加上"&“操作符。
scanf中要求给出变量地址,如给出变量名则会出错,如
scanf(”%d",a);是非法的,应改为scanf(“%d”,&a);才是合法的
C编译在碰到空格,TAB,回车或非法数据(如对“%d”输入“12A”时,A即为非法数据)时即认为该数据结束。
判断是否为字母
int ch =0;
//输入
while ( (ch=getchar () !=EOE)//多组输入
{
if((ch>='a' && ch<='z”)||(ch>='A'&& ch<='8'))
printf ("YES\n");
else
printf ("NO\n");
getchar ();//消耗掉\n}
return 0;
getchar()输入的一串字符,可以将其单个分开存储;getline:一行信息。
int main(){
printf ( " code addr: %p\n" , main);
char *str = "hello bit! ";
printf( " read only addr: %pln" , str);//字符常量区的地址,hello bit!在字符常量区
printf( " read only addr: %pln" , &str);//str的地址,str在栈
}
char a[1000] = {0};
int i=0;
for(i=0; i<1000; i++)
{
a[i] = -1-i;
}
printf("%d",strlen(a));
a是字符型数组,考虑到a[i]其实是字符型,如果要为0,则需要-1-i的低八位要是全0,也就是问题简化成了“寻找当-1-i的结果第一次出现低八位全部为0的情况时,i的值”(因为字符数组下标为i时第一次出现了尾零,则字符串长度就是i)。只看低八位的话,此时-1相当于255,所以i==255的时候,-1-i(255-255)的低八位全部都是0,也就是当i为255的时候,a[i]第一次为0,所以a[i]的长度就是255
char msg[64] = "hello bit ! \n" ;
memcpy(msg+1,msg,strlen(msg)-1) ;
//结果=hhello bit!
char msg[64] = "hello bit! \n" ;char buffer[64];
mymemcpy (msg+1,msg,strlen (msg));//msg拷给msg+1
printf("%s \n", msg) ;//结果=hhhhhhhhhhhh,内存区间重叠的问题,从高地址到低地址方向拷贝才不会发生错误,dst地址 >src地址 && dst < src + len
char arr[]={'a','b'};
strlen (arr):随机值,但至少是2
strlen:获取字符串的有效长度的,结尾标记"0’不包含在内,从前往后依次检测,直到遇到\0是就终止检测。函数,
sizeof会将空字符\0计算在内。操作符(关键字),
char dog[=“wang\0miao”;那么sizeof(dog)与strien(dog)分别是10,4
添加链接描述
解
添加链接描述
从两侧进行统计,如果不同,则删除任意一个,在判定是否是回文,如果是,下标就是删除数据的下标,如果不是,就 是另一个元素的下标
#include
#include
using namespace std;
bool IsPalindrome(string &s, int *start, int *end)
{ int i = 0; int j = s.size() - 1;
bool result = true;
while(i <= j)
{
if(s[i] != s[j])
{ result = false;
break; }
i++,j--;
}
if(start != nullptr)
*start = i;
if(end != nullptr)
*end = j;
return result;
}
int main()
{
int num = 0;
cin >> num;
while(num)
{
string s;
cin >> s;
int start = 0;
int end = s.size() - 1;
if(IsPalindrome(s, &start, &end))
{ cout << -1 << endl; //已经是回文了
}
else
{
s.erase(end, 1);
if(IsPalindrome(s, nullptr, nullptr))
{ cout << end << endl; }
else
{cout << start << endl; }
}
num--;
}
}
acbba,第2次检测时,c不等于b,删除b,检测是否是回文,否,则要删除的一定是c
class Solution {
public:
bool isLetter(char ch) {
if((ch>='0'&&ch<='9')
||(ch>='A'&&ch<='Z')||(ch>='a'&&ch<='z'))
{return true;}return false;}
bool isPalindrome(string s) {
for (auto& e : s)//s里每个元素赋值给e,使用引用,这样s改变元素,则e也会改变
{
if (e >= 'A'&& e <= 'Z')
e += 32;//全转为小写字母
}
int left = 0, right = s.size() - 1;
while (left < right)
{
while (left < right && !isLetter(s[left])){
++left;
}
while (left < right && !isLetter(s[right]))
{--right;}
if (s[left] != s[right])
return false;//不是回文
++left;
--right;
}
return true;
}};
添加链接描述
#include
#include
using namespace std; // 判断是否是回文
bool IsCircleText(const string& s)
{
size_t begin = 0;
size_t end = s.size()-1;
while(begin < end)
{
if(s[begin] != s[end])
return false;
++begin;
--end;
}return true;
}
int main() {
std::string str1, str2;
getline(cin, str1);
getline(cin, str2);
size_t count = 0;
for (size_t i = 0;i <= str1.size(); ++i)
{ // 将字符串2插入到字符串1的每个位置,再判断是否是回文
string str = str1;
str.insert(i, str2);
if(IsCircleText(str))
++count;
}
cout<<count<<endl;
return 0;
}
str1 :aba;str2: b;str:baba abba abba abab
添加链接描述
题
void Reverse(string &str, int start, int end)
{ while (start < end)
{ char temp = str[start]; str[start] = str[end]; str[end] = temp; start++; end--;
} }
string ReverseSentence(string str) {
//先局部逆置,再整体逆置
if(str.size() == 0)
{ return str; }
int i = 0; int j = i;
int len = str.size();
while(i < len)
{
while( i < len && !isspace(str[i]))
i++; //让i一直往后走,碰到第一个空格
Reverse(str, j, i-1); //逆置当前有效子串,闭区间
while( i < len && isspace(str[i]))
i++; //越过所有空格,指向下一个有效子串的开始
j = i;
//保存起始位置
}//走到这里,一定是 i == str.size()了,但是最后一个有效子串并没有被逆置,逆置之。i:最后一个元素的下一个位置,已经越界,j:最后1个单词的起始位置
Reverse(str, j, i-1);i-1:最后1个单词的下标:len-1
Reverse(str, 0, i-1); //最后在整体逆置
return str;
}
方法1:
static void Swap (char *p,char *q)
{assert (p) ;
assert(q) ;
*p=*p^*q;
*q=*p^*q;*p=*p^*q;//形参指向实参
}
void ReverseString(char *s){
assert(s);
char *start =s,
char *end = s + strlen(s) - 1;//-1的原因:如果不-1,则交换后把放在最前面,什么都打印不出来
while (start<end){
Swap(start,end) ;start++;
end--;}}
int main(){
//char *str ="abcd1234";字符常量区保存:"abcd1234,不可以修改
char str[] ="abcd1234";//数组 栈
printf ("before: %s \n", str);
ReverseString(str) ;
printf("after : %s \n", str) ;}
方法2:
#include
#include
#include
using namespace std;
int main()
{
string s; // 注意这里要使用getline,cin>>s遇到空格就接收结束了
getline(cin, s);
reverse(s.begin(), s.end()); // 翻转整个句子
auto start = s.begin();
while (start != s.end())
{
auto end = start;
while (end != s.end() && *end != ' ')
end++;
reverse(start, end); // 翻转单词,start end区间就是一个单词
if (end != s.end())
start = end + 1;
else
start = end;
}
cout << s << endl;
return 0;
}
用另一个字符串存储进行逆序输出,cin>>s接收输入,遇到空格就结束了,自然就分割开了每个单词,其次将每次接收到的单词拼接到之前串的前面就逆置过来了
方法3:
#include
#include
using namespace std;
int main()
{
string s1, s2;
cin >> s2;
while (cin >> s1)
s2 = s1 + " " + s2;
cout << s2 << endl;
return 0;
}
添加链接描述
void ReverseString(char *start,char *end){
assert(start) ;
assert(end) ;
while (start < end)
{char temp = *start;*start =*end;
*end = temp;start++,end--;}}
void LeftMove(char str[],int len,int num)
{assert(str) ;
num %= len;
// abcd1234 换4个 abcd 1234
// dcba 4321 1234abcd,局部逆置,再整体逆置
ReverseString(str,str + num - 1) ;
ReverseString(str +num,str + len - 1) ;//-1即减去\0
ReverseString(str,str + len - 1) ;}
int main(){
char str[] = "abcd1234";int num = 3;
LeftMove(str,strlen(str), num) ;
printf("after: %s \n", str) ;//d1234abc
system("pause") ;
return 0;}
//方法2,构建双倍串
void LeftMove(char str[],int len,int num)
{assert(str) ;
num %= len;
char *p = malloc(sizeof(char)*len*2+1);
if (NULL== p){
return;}
strcpy(p,str); //"abcd1234"
strcat(p,str) ; //"abcd1234""abcd1234"
strncpy (str,p+num,len) ;
free(p);}
添加链接描述
void ReverseString(string &str, int start, int end)
{ while(start < end)
{ char temp = str[start]; str[start] = str[end]; str[end] = temp; start++, end--; }
}
string LeftRotateString(string str, int n)
{ if(n == 0 || str.empty())
{ return str; }
n %= str.size(); //去除重复移动
ReverseString(str, 0, n-1); //前半部分逆置
ReverseString(str, n, str.size()-1); //后半部分逆置
ReverseString(str, 0, str.size()-1); //整体逆置
return str; }
给定s1 =AABCD和s2 = BCDAA,返回1,给定s1=abcd和s2=ACBD,返回0
int CheckString(char *s1,char *s2){
assert(s1);
assert(s2) ;
int len1 = strlen(s1) ;int len2 = strlen(s2);
if (len1 == len2){
while (len1){
if (strcmp(s1,s2) == 0){
return 1;}
LeftMove(s2,len2,1);len1--;
}
}return 0;
}
int main(){
char str1[] = "abcd1234";
char str2[] = "1234abcd";
int result = CheckString(str1, str2) ;
printf("result %d\n", result) ; }
char p1[15]="abcd" ,*p2= “ABCD",
str[50]= “xyz"";
strcpy(str+2,strcat(p1+2,p2+1));
printf(""%s" ,str);//xycdBCD
给定一个字符串 S,返回 “反转后的” 字符串,其中不是字母的字符都保留在原地,而所有字母的位置发生反转。输入:"ab-cd!"输出:“dc-ba!”
class Solution {
public:
bool isLetter(char ch){
if (ch >= 'a' && ch <= 'z')
return true;
if (ch >= 'A'&& ch <= 'Z')
return true;
return false;
}
string reverseOnlyLetters(string S){
if (S.empty())
return S;//如果是空,S.size() - 1为-1,即最大值,越界
size_t begin = 0, end = S.size() - 1;
while (begin < end)
{
while (begin < end && !isLetter(S[begin]))
++begin;//不是字符则不交换,遇到字符才交换
while (begin < end && !isLetter(S[end]))
--end;
swap(S[begin], S[end]);
++begin;//交换之后继续往后检查迭代,继续往后走1步
--end;
}
return S;
}};
添加链接描述
添加链接描述
递归的终止条件:通配符或者字符串遇到’\0’。当他们同时结束
#include
#include
using namespace std;
bool match(const char* pattern, const char *str)
{ //当前字符结束,返回true
if (*pattern == '\0' && *str == '\0')
return true; //两个字符串有一个先结束,则返回false
if(*pattern == '\0' || *str == '\0')
return false;
if (*pattern == '?')
{
if (!isdigit(*str) && !isalpha(*str))
return false; //遇到?号,匹配一个字符,跳过一个位置
return match(pattern + 1, str + 1);
}
else if (*pattern == '*')
{// 遇到*号,匹配0个(str不挪动),1个(两者都向前挪动一个字符)或多个(str向前挪动一个字符) :3种情况
while(*pattern=='*')
{
pattern++;
}
pattern--;
if(!isdigit(*str) && !isalpha(*str))
return match(pattern+1,str);递归
return match(pattern + 1, str) || match(pattern + 1, str + 1) || match(pattern, str + 1);
}else if (tolower(*pattern) == tolower(*str)) //忽略大小写
{ //如果当前字符相等,匹配下一个字符
return match(pattern + 1, str + 1);
}
return false;
}
int main()
{
string pattern, str;
while (cin >> pattern >> str)
{
bool ret = match(pattern.c_str(), str.c_str());
if (ret)
cout << "true" << endl;
else
cout << "false" << endl;
}
return 0;
}
子串:cdefg
子序列:adgk
字符串:abcdefghijk
#include
#include
#include
#include
using namespace std;
int main()
{
string str1, str2;
while (cin >> str1 >> str2)
{
//永远保证s1:最短
if (str1.size() > str2.size())
swap(str1, str2);
int len1 = str1.size(), len2 = str2.size();
int i, j, start = 0, max = 0;
start :最长子串在短字符串 s1 中出现的起始位置,
max:当前最长子串的长度;初始化所有值为 0
vector<vector<int>> MCS(len1 + 1, vector<int>(len2 + 1, 0));
for (i = 1; i <= len1; i++)
{
for (j = 1; j <= len2; j++)
{
if (str1[i - 1] == str2[j - 1])
MCS[i][j] = MCS[i - 1][j - 1] + 1;最优解,动态规划
//如果有更长的公共子串,更新长度
if (MCS[i][j] > max)
{
max = MCS[i][j];
//以i结尾的最大长度为max, 则子串的起始位置为i - max
start = i - max;
}
}
}
cout << str1.substr(start, max) << endl;
}
return 0;
}
#include
#include
using namespace std;
int main()
{
int max = 0; //max初值.
string str1, str2;
while (cin >> str1 >> str2)
{
int len1 = str1.size();
int len2 = str2.size();
int max = 0;
//所有值初始化为0
vector<vector<int>> dp(len1, vector<int>(len2, 0));
//计算dp
for (int i = 0; i < len1; i++)
{
for (int j = 0; j < len2; j++)
{
//如果当前结尾的字符相等,则在dp[i-1][j-1]的基础上加1
if (str1[i] == str2[j])
{
if (i >= 1 && j >= 1)
dp[i][j] = dp[i - 1][j - 1] + 1;
else
dp[i][j] = 1; //dp[i][0] or dp[0][j]时
}
//更新最大值
if (dp[i][j] > max)
max = dp[i][j];
}
}cout << max << endl;
}
return 0;
}
添加链接描述
cur去记录连续的数字串,如果遇到不是数字字符,则表示一个连续的数字串结束了,则将数字串跟之前的数字串比较,如果更长,则更新更长的数字串更新到res。
#include
#include
using namespace std;
int main() { string str,res,cur;
cin>>str;
for(int i=0;i<=str.length();i++)
{
// 数字+=到cur
if(str[i]>='0' && str[i]<='9')
{ //字符0和数字0不一样,i走到字符串的\0时,不会进入这里面
cur+=str[i];
}
else {
// 找出更长的字符串,则更新字符串
if(res.size() < cur.size())
res=cur;
else
cur.clear();
}
}
cout << res;
return 0;
}
删除公共字符
#include
#include
using namespace std;
int main()// oj中IO输入字符串最好使用getline
{ string str1,str2;
getline(cin, str1); getline(cin, str2); // 使用哈希映射思想先str2统计字符出现的次数
int hashtable[256] = {0};
for(size_t i = 0; i < str2.size(); ++i)
{
hashtable[str2[i]]++;
}//不要str1.erases(i) 边遍历,边erase,容易出错。
string ret;
for(size_t i = 0; i < str1.size(); ++i)
{
if (hashtable[str1[i]] == 0) ;ret += str1[i];
}cout << ret << endl; return 0;
}
给定一个字符串,找到它的第一个不重复的字符(小写=26个),要求时间复杂度优化到0(N),并返回它的索引。如果不存在,则返回 -1。s = "leetcode"返回 0
//计数排序思想;a(ASCII码是97)映射位置0:相对位置;
//0(N)=0(2N)=0(N)【计算字符出现的次数,计数,要遍历1次】+0(1)【找第1次出现时的下标,映射关系,拿每个字符找其次数】
class Solution {
public:
int firstUniqChar(string s) {
int count[26] = { 0 };
for (auto ch : s){//等价于for (char e : s)//O(N)
count[ch-'a']++;//统计次数
}初始化为0,以哈希方式相对映射
for (int i = 0; i < s.size(); ++i){//O(N)
if (count[s[i] - 'a'] == 1)
//找字符出现的次数,找第1次出现时,//O(1)//[]的不一样意义:最内层[]:函数调用,外层[]:数组解引用
return i;
}
return -1;
}};
#include
#include
using namespace std;
// 暴力法··o(n ^ 2),找出字符串中第一个只出现一次的字符
char getFirstonechar(const string &str)
{
int j;
for (int i = 0; i < str.size(); ++i)
{
for (j = 0; j < str.size(); ++j)
{
if (j == i)//排除自己跟自己比较.. .. ·:
continue;
if (str[j] == str[i])
break;
}
if (j >= str.size())
return str[i];
}
return -1;
}
char getFirstonechar_2(const string &str){
int hash[256] = { 0 };//hash法,2次for,复杂度:O(2n)
for (int i = 0; i < str.size(); ++i)//统计字符的次数
hash[str[i]]++;
for (int i = 0; i < str.size(); ++i)
{
if (hash[str[i]] == 1)
return str[i];
}
return -1;
}
// string类函数查找法
char getrirstonechar_3(const string &str)
{
for (int i = 0; i < str.size(); ++i)
{
int index1 = str.find(str[i]);
int index2 = str.rfind(str[i]);
if (index1 == index2)
return str[i];
}
return -1;
}
int main()
{
string str;
char res;
while (getline(cin, str))
{
res = getrirstonechar_3(str);
if (res == -1)
cout << -1 << endl;
else
cout << res << endl;
}
return 0;
}
字符串最后一个单词的长度,单词以空格隔开,字符串长度小于5000。
(注:字符串末尾不以空格为结尾)输入:hello nowcoder输出:8
#include
#include
using namespace std;
int main()
{ string s;
//cin>>s;//不使用cin输入,cin把空格当成输入的分隔,如输入:ABS T,输出:3,把T消失
getline(cin,s);//得到1行,含空格则使用getline
size_t pos = s.rfind(' ');//找空格
if (pos == string::npos){
cout << s.size()<<endl;//没有找到空格
}
else{
cout << s.size() - pos - 1 << endl;//-1是减去空格长度
} }
给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和并同样以字符串形式返回。你不能使用任何內建的用于处理大整数的库(比如 BigInteger), 也不能直接将输入的字符串转换为整数形式。输入:num1 = “11”, num2 = "123"输出:“134”
class Solution {
public:
string addStrings(string num1, string num2) {
string ret;
int end1 = num1.size() - 1,
end2 = num2.size() - 1;
char next = 0;//进位
while (end1 >= 0 || end2 >= 0)//2个数字都结束,才结束
{
char x1 = 0,x2 = 0;
if (end1 >= 0)
{
x1 = num1[end1] - '0'; --end1;
}
if (end2 >= 0)
{
x2 = num2[end2] - '0'; --end2;
}char retch = x1 + x2 + next;
if (retch >= 10)
{
retch -= 10; next = 1;
}
else{
next = 0;
}
ret += (retch + '0');
}
if (next == 1)
ret += '1';
reverse(ret.begin(), ret.end());//如果使用头插,需要挪动数字,O(N*N);尾插O(N)+逆置O(N)=O(2N)
return ret;
}};
添加链接描述
class Solution 方法1:
{
public: int StrToInt(string str) {
if (str.empty()) return 0;
int symbol = 1;
if (str[0] == '-') //处理负号
{
symbol = -1; str[0] = '0'; //这里是字符'0',不是0
}
else if(str[0] == '+') //处理正号
{
symbol = 1; str[0] = '0';
}
int sum = 0;
for(int i=0;i<str.size();++i) {
if(str[i] < '0' || str[i] > '9')
{
sum = 0; break;
}
sum = sum *10 + str[i] - '0';
}
return symbol * sum;
}
};
int my_atoi(const char *str)//字符串转整数
{
assert(str);
const char *p = str;
int flag = 1;
//去掉前缀其他非法字符
while (*p && !isdigit(*p))
{
if (*p == '-'){ break; }
p++;
}
if (*p == '-'){
flag = -flag; p++;
}
if (!isdigit(*p)){
errno = 1;//非法字符串
return 0;
}
long long res = 0; //8字节,只使用4字节
while (isdigit(*p) && *p){
res = res * 10 + flag*(*p - '0’) ;
if (res > INT_MAX || res < INT_MIN){
errno = 2;
return res;
}
p++;
}
return (int)res;
}
int main()
{const char *str = "abc-$ : -12349999" ;
int x = my_atoi(str) ;
if (errno == 0){
printf("%d\n", x);}
else{
printf("error: %d ! \n", errno) ;
}}
1 有王joker JOKER,直接赢
2 分开2者牌,同类型牌
3 2者类型不同,判断是否有炸弹
4 错误ERROR
#include
#include
#include //count
using namespace std;
string indMax(const string &line){一直查找joker JOKER,直到字符串末尾
if (line.find("joker JOKER") != string:: npos)
return "joker JOKER";
int dash = line.find('-');//分开两手牌
string car1 = line.substr(0, dash);
string car2 = line.substr(dash + 1);
//获取两手牌的张数
int car1_cnt = count(car1.begin(), car1.end(), ' ') + 1;
int car2_cnt = count(car2.begin(), car2.end(), ' ') + 1;
//获取两手牌的各自第一张牌
string car1_first = car1.substr(0, car1.find(' '));
string car2_first = car2.substr(0, car2.find(' '));
if (car1_cnt == car2_cnt)//两手牌的类型相同
{
string str = "345678910JQKA2jokerJOKER";
if (str.find(car1_first) > str.find(car2_first))
return car1;
return car2;
}
if (car1_cnt == 4)//是炸弹....
return car1;
else if (car2_cnt == 4)//....·
return car2;
return "ERROR";
}
int main()
{
string line;string res;
while (getline(cin,line))
{
res = indMax(line);
cout << res << endl;
}
return 0;
}