c/c++筆試中程式設計題總結
1.請實現字串右迴圈移位函式,比如:“abcdefghi”迴圈右移2位就是“hiabcdefg”.
函式原型:void RightLoopMove(char *pStr, unsigned short steps)
函式引數說明: pStr: Point to a ‘\0’ terminated string steps: The rotate shift numbers*/
解法一:常規解法(萬不得已時候考慮使用),直接採用指標移動
void _fun(char *pStr, unsigned short steps) { assert(pStr != NULL && steps > 0); int n = strlen(pStr);//abcdefghi char * p = pStr; //p指向 abcdefghi char *back = (p + n - steps);//back 指向 ghi char *temp = (char*)malloc(sizeof(char)*steps + 1);//開闢temp 存取要移動到前面的字元 strcpy(temp, back); //先把後面要移動的字元拷貝到temp while (p != back) { for (int i = 0; i < n; ++i) { *(pStr + steps + i) = *(p + i); } p++; } strcpy(pStr, temp); free(temp); } int main() { char *a = (char *)malloc(sizeof(char) * 20); strcpy(a, "abcdefghi"); char * p = a; while (*p != '\0') { cout << *p; p++; } cout << endl; _fun(a, 2); p = a; while (*p != '\0') { cout << *p; p++; } cout << endl; free(a); return 0; }
解法二:採用臨時空間來存放一個值,先把最後一個值存放其中,然後整體右移動 時間複雜度為O(n+m)
void RightLoopMove(char *pStr, unsigned short steps) { assert(pStr != NULL && steps > 0); int str_len = strlen(pStr); steps %= str_len; char tmp; while (steps > 0) { tmp = *(pStr + str_len - 1); for (int i = str_len - 1; i > 0; --i) { *(pStr + i) = *(pStr + i - 1); } pStr[0] = tmp; steps--; } }
2..功能:實現對一個8 bit資料(unsigned char型別)的指定位(例如第n位)的置0或者置1操作,並保持其他位不變。
函式原型:
void bit_set(unsigned char *p_data, unsigned char position, bool flag)
函式引數說明: P_data 是指定的源資料,position是指定位(取值範圍1~8);flag表示是置0還是置1操作,true: 置1 flase:置0*/
思路:通過移動1,或等和與等取反(移動後的1)來實現位操作
void bit_set(unsigned char *p_data, unsigned char position, bool flag) { assert(p_data != NULL, position >= 1 && position <= 8); //邊界值的問題 /*if (p_data == NULL){} if (position < 1 || position >8){}*/ if (flag)//1 { *p_data |= ((0x01) << (position - 1)); } else //0 { *p_data &= ~((0x01) << (position - 1)); } }
3.有一個16位的整數,每4位為一個數,寫函式求他們的和。
例如:整數1101010110110111,和 1101+0101+1011+0111 = 13+5+11+7=36*/
方法一:
int fun(unsigned short a)
{
assert(a <= 65535);
int x[4] = { 0 };
int y[4] = { 0 };
int result = 0;
x[0] = 15; x[1] = 240; x[2] = 3840; x[3] = 61440;
for (int i = 0; i < 4; i++)
y[i] = x[i] & a;
y[1] >>= 4; y[2] >>= 8; y[3] >>= 12;
for (int i = 0; i < 4; i++)
result += y[i];
return result;
}
int main()
{
unsigned short a = 54711;
int b = sum(a);
cout << b << endl;
return 0;
}
方法二:
int sum(unsigned short value)
{
int sum = 0;
for (int i = 0; i < 4; ++i)
{
sum += ((value&(0x0f << i * 4)) >> (i * 4));
}
return sum;
}
4.給出unsigned char value, 判斷value中的二進位制1的個數,要求演算法效率儘可能高
方法一:
int main()
{
unsigned char value = 'A';
int a[30], i = 0, x = (int)value, y, n = 0;
while (x != 0)
{
y = x % 2;
a[i] = y;
i++;
x = x / 2;
}
i--;//按照迴圈i多加一次,所以要減去一
for (; i >= 0; --i)
{
printf("%d", a[i]);
}
cout << endl;
for (int i = 0; i < 30; ++i)
if (a[i] == 1)
n++;
cout << "value中的二進位制1的個數 = " << n << endl;
}
方法二:
int main()
{
unsigned char v = '15';
int count = 0;
while (v)
{
count += v & 0x1;
v >>= 1;
}
cout << count << endl;
return 0;
}
方法三:
int fun(int v)
{
int count = 0;
while (v)
{
v &= (v - 1);
count++;
}
return count;
}
int main()
{
int i = fun(100);
cout << i << endl;
return 0;
}
5、通過鍵盤輸入一串小寫字母(a~z)組成的字串。請編寫一個字串壓縮程式,將字串中連續出席的重複字母進行壓縮,並輸出壓縮後的字串。
壓縮規則:
1、僅壓縮連續重複出現的字元。比如字串"abcbc"由於無連續重複字元,壓縮後的字串還是"abcbc"。
2、壓縮欄位的格式為"字元重複的次數+字元"。例如:字串"xxxyyyyyyz"壓縮後就成為"3x6yz"。
要求實現函式:
void stringZip(const char *pInputStr, long lInputLen, char *pOutputStr);
輸入pInputStr: 輸入字串lInputLen: 輸入字串長度
輸出 pOutputStr: 輸出字串,空間已經開闢好,與輸入字串等長;
注意:只需要完成該函式功能演算法,中間不需要有任何IO的輸入輸出
示例
輸入:“cccddecc” 輸出:“3c2de2c”
輸入:“adef” 輸出:“adef”
輸入:“pppppppp” 輸出:“8p”
#include<stack>
void stringZip(const char *pInputStr, long lInputLen, char *pOutputStr)
{
assert(pInputStr != NULL);
stack<int> st;
long n = strlen(pInputStr);
const char *p = pInputStr;
char *out = pOutputStr;
int count = 1;
while (*p != '\0')
{
if (*p == *(p + 1))
{
count++;
}
else
{
if (count != 1)
{
while (count)
{
st.push(count % 10);
count /= 10;
}
while (!st.empty())
{
*pOutputStr++ = st.top() + '0';
st.pop();
}
}
count = 1;
*pOutputStr++ = *p; //cout << *p;//
}
*pOutputStr = '\0';
p++;
}
}
int main()
{
const char *str = "cccddecc";
long n = strlen(str);
char output[30] = { 0 };
stringZip(str, n, output);
/*char *p = output;
while (p != NULL)
{
cout << *p;
p++;
}*/
for (int i = 0; i < 10; i++)
cout << output[i];
cout << endl;
return 0;
}
6、如果一個字串str, 把字串str前面任意的部分挪到後面形成的字串叫做str的旋轉詞,比如str=”12345”,
str的旋轉詞有”12345”, ”23451”, “34512”, “45123”, “51234”, 給定兩個字串a和b,請判斷a和b是否為旋轉詞。
int main()
{
char str[] = "12345";
char RotatetWord[] = "45123";
int count = 0, n = strlen(str) + 1;
char *temp;
temp = (char*)malloc(sizeof(char) * 2 * n - 1);
strcpy(temp, str);
strcat(temp, str); //tmp 1234512345
char *T = temp, *R = RotatetWord;
while (*R != '\0')
{
while (*T != '\0')
{
if (*R == *T)
{
count++;
R++;
}
T++;
}
}
if (count == (n - 1))
{
cout << "a是b的旋轉詞。" << endl;
}
else
{
cout << "a不是b的旋轉詞。" << endl;
}
return 0;
}
7、給定一個字元型別的陣列chas, 請在單詞間做逆序調整, 只要做到單詞順序逆序即可,對空格的位置沒有特別要求。
例如:如果把chas看作字串為“dog loves pig”, 調整為 “pig loves dog”
如果把chas看作字串為 “ I’ m a student . ” 調整為 “student. a I’m ”
void reverse(char *str, int start, int end)
{
while (start <= end)
{
char tmp = str[start];
str[start] = str[end];
str[end] = tmp;
start++;
end--;
}
}
void RotateWord(char*str)
{
if (str == NULL || *str == '\0')
return;
int len = strlen(str);
reverse(str, 0, len - 1);/*先把整個字串倒過來*/
/////////////////////////
int left = 0, right = 0;
for (int i = 0; i <= len; ++i)
{
if (str[i] == ' '|| str[i] == '\0')
{
right = i - 1;
reverse(str, left, right);
left = i + 1;
}
}
}
int main()
{
char str[] = "dog loves pig";
RotateWord(str);
cout << str << endl;
return 0;
}
8.給定一個字元陣列,判斷字元陣列中是否所有的字元都只出現過一次
根據兩個要求,分別實現兩個函式。在保證額外空間複雜度為O(1)的前提下,實現時間複雜頓儘量低的方法。
bool oneCharacter(char* str) //char a[] = "awwbc";
{
int n = strlen(str),i = 0,j=i+1;
while (*str != '\0')
{
while(*(str+j) !='\0')
{
if (*(str) == *(str + j))
{
return false;
}
++j;
}
j = i+1;
++i;
++str;
}
return true;
}
int main()
{
char a[] = "awwbc";
bool result = oneCharacter(a);
cout << result << endl;
return 0;
}
9.給定一個字串str, 返回str的最長無重複字元子串的長度;
例如:str=”abcd” ,返回 4 str=”aabcb”, 最長無重複字元子串為“abc”, 返回3
int lengthOfLongestSubstring(string s) {
// write your code here
int ret = 0;
map<char, int> m;
int start = 1;
for (int i = 1; i <= s.length(); i++)
{
char c = s[i - 1];
if (m[c] >= start)
{
start = m[c] + 1;
m[c] = i;
}
else
{
m[c] = i;
ret = max(ret, i - start + 1);
}
}
return ret;
}
int main()
{
char str[] = "aabcb";
int i = lengthOfLongestSubstring(str);
cout << i << endl;
return 0;
}
10.請編寫函式實現,找出一個字元陣列中第一個只出現一次的字元。
void Judge(char *str)
{
assert(str != NULL);
int i;
int pindu = 256;
int Index = 23;
int cnt = 0;
int Count[256] = { 0 };
int sequence[256] = { 0 };
for (i = 0; str[i] != '\0'; i++)
{
Count[(int)(*(str + i))] ++;
sequence[(int)(*(str + i))] = cnt++;
}
for (i = 0; i < 256; i++)
{
if (Count[i] == 1)
{
if (sequence[i] < pindu)
{
pindu = sequence[i];
Index = i;
}
}
}
cout << "陣列下標為:" << pindu << endl;
cout << "第一次只出現一次的字元為: " << str[pindu] << endl;
}
int main()
{
char str[] = "aaaaaassssssbsssddggaafewfasfwefewwffadaccbeez"; //qwertyuiqwer
Judge(str);
return 0;
}