プログラミングスキルが少しずつ向上します!
序文
大事なことは3回言いましょう!
勉強!勉強!勉強!
1. 表情判定
コード スニペットについては、次の説明が正しいです ( )
t=0;
while(printf("*"))
{
t++;
if (t<3)
break;
}
A: ループ制御式は 0 と同等です
B: ループ制御式は「0」と同等です
C: ループ制御式は不正です
D: 上記のステートメントはどれも正しくありません
質問分析:
print("*") 関数呼び出しの戻り値は文字列内の文字数、つまり 1 であるためです。
したがって、while の後の条件は常に true となるため、ループ制御式は '0' と等価になります (文字 '0' は 0 ではありません)。
正解はB
問題の答え:
B
2. Assii コードの理解と応用
以下のプログラムを実行した場合、1abcedf2df <Enter>を入力すると出力結果は( )となります。
#include <stdio.h>
int main()
{
char ch;
while ((ch = getchar()) != '\n')
{
if (ch % 2 != 0 && (ch >= 'a' && ch <= 'z'))
ch = ch - 'a' + 'A';
putchar(ch);
}
printf("\n");
return 0;
}
A: 1abcedf2df
B: 1ABCEDF2DF
C: 1AbCEdf2df
D: 1aBceDF2DF
問題分析:
ch の ASCII コード値が奇数であるかどうかを考慮し、次に小文字であるかどうかをチェックし、両方を満たす場合は大文字に変更します。
質問の答え:
C
3. ループジャンプ判定
C 言語の Break ステートメントは、最も近いループからのみジャンプできることはわかっていますが、場合によっては複数のループからジャンプする必要がある場合があります。以下の複数のループからジャンプする正しい方法は [複数選択] ( ) A: を記述します。関数としてプログラムする
return で関数を終了してループから抜け出す
B: 外側のループ条件を変更します。たとえば
for( int i = 0 ; i < MAX1 ; i ++ )
{
for( int j = 0 ; j < MAX2 ; j ++ )
{
if( condition )
{
i = MAX1;
break;
}
}
}
C: 外側のループに判定条件を設定する例
for( ; symbol != 1 && condition2 ; )
{
for( ; symbol != 1 && condition3 ; )
{
if( condition1 )
symbol = 1 ;
}
}
D: たとえば、外側のループの後にブレークを追加します。
for( ; condition2 ; )
{
for( ; condition3 ; )
{
if( condition1 )
symbol = 1 ;
}
if(symbol == 1 )
break ;
}
問題分析:
この問題は、多重レベルのループから抜け出す方法を整理することを目的としています。各選択肢は正解です。コードは疑似コードであり、条件は論理式を表します。
質問の答え:
ABCD
4. 数値が昇順配列に出現する回数
質問リンクOJ リンク
問題分析:
トラバーサルでも解決できますが、配列は降順ではありません。二分探索の考え方が最適です。最初に二分探索で左端のデジタル位置を見つけ、次に右端のデジタル位置を二分探索します。 2 つの位置の減算 + 1 が長さです。
中央の値が探している値より大きい場合: 探している数字は右側にある必要があり、左側 = Mid + 1;
中央の値が探している値より小さい場合: 探している数字は左側にある必要があり、右側 = 中央 - 1;
中央の値は探している値と同じです。値は同じです:
検索する左端の数値: Mid が左の場合は Mid を返し、そうでない場合は right=mid-1 にリセットし、中心を左に継続的にシフトします。検索する右端の数値: Mid が右の場合は Mid を返します
。 left=mid+1 にリセットし、継続的に中心を右にシフトします
。
int get_last_or_first_idx(int* data, int len, int k,int flag) {
int left = 0, right = len - 1, mid;//左右指针下标及中间结点下标
while (left <= right) {
mid = left + (right - left) / 2;//找到中间结点
if (data[mid] > k)
right = mid - 1;//如果中间节点大于k,则将右节点左移
else if (data[mid] < k)
left = mid + 1;//如果中间节点小于k,则将左节点右移
else {
//如果中间节点值等于k,则判断flag的值来区分找的是哪边
if (flag == 0) {
if (mid == left || data[mid - 1] != k) return mid;//如果中间结点等于k,且前一个结点不等于k,以及和left位置相同,则找到最左边的k,返回下标
else right = mid - 1;
} else {
if (mid == right || data[mid + 1] != k) return mid;//如果中间结点等于k,且后一个结点不等于k,以及和right位置相同,则找到最右边的k,返回下标
else left = mid + 1;
}
}
}
return -1;
}
int GetNumberOfK(int* data, int dataLen, int k ) {
if (dataLen == 0) return 0;
int left = get_last_or_first_idx(data, dataLen, k, 0);
int right = get_last_or_first_idx(data, dataLen, k, 1);
if (left == -1 && right == -1) return 0;
return right - left + 1;//左右下标相减得到k的个数
}
5. 整数変換
質問リンク: OJ リンク
ヒント:
A と B の範囲は [-2147483648, 2147483647] です。
質問分析:
実際、何ビット変更する必要があるかを尋ねる場合、問題は何ビットが異なるかということです。なぜなら、変更できるのは何ビットだけ異なるからです。
質疑応答:
int convertInteger(int A, int B){
int a=A^B;//相同为0,相异为1
double count=0;
for(int i=0;i<32;i++){
if((a>>i)&1==1){
//通过与1与,得到求出的数二进制序列中有多少个1,从而确定个数;
count++;
}
}
return count;
}
6. ループ文の応用
次の文のうち正しいものはどれですか ( )
A:break 文はループ本体と switch 文でのみ使用できます
B:break がループ本体内の switch 文の本体にある場合、その機能は次のとおりです。 switch ステートメントの本体から飛び出て、ループ本体を終了します。C
: continue ステートメントを実行する機能は、ループ本体内の残りのステートメントを実行した後にループを終了することです。D
: continue ステートメントは、次のような場合には使用できません。 while ステートメントと do-while ステートメント。
質問分析:
Break ステートメントは通常、loop ステートメントと switch ステートメントで使用されます。switch ステートメントで Break を使用すると、プログラムは switch から抜け出して、switch の後のステートメントを実行できます。break を
do-while、for、while ループ ステートメントで使用すると、プログラムはループを終了して、つまり、条件が満たされるとループが開始されます。
continue ステートメントの機能は、ループ本体内の残りのステートメントをスキップし、次のループの実行を強制することです。選択肢 B、C、D に誤りがあります。したがって、選択肢Aの正解は次のとおりです
。
7. 関数呼び出し
関数 fun と実際のパラメータグループの記述が次の形式であるとします。関数呼び出しステートメントでは、正しいものは ( ) です。
void fun(char ch,float x[]);
float a[10];
A: fun(“asd” , a[]); B: fun('x' , A); C: 楽しい('68' , 2.8); D: 楽しい(32 , a);
質問分析:
オプション A の配列にパラメーターを渡すには、配列名を記述するだけで済みます。a[] は間違っています。オプション B の 2 番目のパラメーターが大文字で書かれているのは間違いです。オプション C の 2 番目のパラメータは浮動小数点数ですが、fun 関数の 2 番目のパラメータは一致しない配列です。fun 関数のパラメータ x には、配列または float * ポインタを渡す必要があります。オプション D の形式のみ正しい。
質問の答え:
D
8. 2 つの配列の交差
質問リンク: OJ リンク
ヒント:
1 <= nums1.length、nums2.length <= 1000
0 <= nums1[i]、nums2[i] <=1000
質問分析:
オプション A の配列にパラメーターを渡すには、配列名を記述するだけで済みます。a[] は間違っています。オプション B の 2 番目のパラメーターが大文字で書かれているのは間違いです。オプション C の 2 番目のパラメータは浮動小数点数ですが、fun 関数の 2 番目のパラメータは一致しない配列です。fun 関数のパラメータ x には、配列または float * ポインタを渡す必要があります。オプション D の形式のみ正しい。
質疑応答:
int* intersection(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize) {
static int arr[1000];//定义静态,防止销毁
*returnSize = 0;//返回数组大小
for (int i = 0; i < nums1Size; i++) {
//将nums1中的每个数遍历nums2找到相同的数
for (int j = 0; j < nums2Size; j++) {
if (nums1[i] == nums2[j]) {
int k = 0;
for (k = 0; k < *returnSize; k++) {
//遍历arr数组看是否已经存在,找到了返回下标
if (arr[k] == nums2[j])
break;
}
if (k == *returnSize) {
//如果k等于*returnSize则说明数组中不存在该数,则向数组中加入该数
arr[*returnSize] = nums2[j];
(*returnSize)++;//返回数组长度+1
}
}
}
}
return arr;
}
9. C言語の基礎
以下の C 言語関数の説明のうち、正しいものは [複数選択] ( )
A: C 言語では、関数は通常、関数ヘッダーと関数本体の 2 つの部分で構成されます。
B: 実際のパラメーターと関数の形式function パラメーターは同じ名前を持つことができます
C: main() で定義された変数は、呼び出される他の関数で直接使用できます
D: C プログラムでは、関数呼び出しを式ステートメントに含めることはできません
質問分析:
main 関数も関数であり、他の関数と並列関係があるため、main 関数で定義されたローカル変数は main 関数内でのみ有効です C エラー; 関数に戻り値がある場合、それは式の中に現れる可能性があります。D 誤った
答え:
AB
10. 写真の整理
質問リンク: OJ リンク
質問分析:
この質問は実際に文字のソートを調べます。各 ASCII 文字はメモリ内に対応する ASCII 値を持ち、メモリ内にデータを保存することでソートできます。
バブル ソート: 隣接するデータを比較および交換し、大きいデータまたは小さいデータを配列の最後に押し戻してから、
ビッグ データのバブリング プロセスの次のラウンドを開始します。
質問に対する答え:
方法 1:
#include <stdio.h>
void Qsort(char*arr,int len){
for(int i=0;i<len;i++){
//冒泡排序
for(int j=0;j<len-i-1;j++){
if(arr[j]>arr[j+1]){
char temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
}
int main() {
char arr[1001] = {
0};
while (scanf("%s", arr)!= EOF) {
char digit[1001] = {
0};//将数字入到该数组
int digits = 0;//数字个数
char upper[1001] = {
0};//将大写字母入到该数组
int uppers = 0;//大写字母个数
char lower[1001] = {
0};//将小写字母入到该数组
int lowers = 0;//小写字母个数
char* ptr = arr;
while (*ptr) {
//查找并添加
if (*ptr >= '0' && *ptr <= '9') {
digit[digits] = *ptr;
digits++;
}
if (*ptr >= 'A' && *ptr <= 'Z') {
upper[uppers] = *ptr;
uppers++;
}
if (*ptr >= 'a' && *ptr <= 'z') {
lower[lowers] = *ptr;
lowers++;
}
ptr++;
}
//进行排序
Qsort(digit,strlen(digit));
Qsort(upper,strlen(upper));
Qsort(lower,strlen(lower));
//进行输出
for (int j = 0; j < digits; j++) {
printf("%c", digit[j]);
}
for (int j = 0; j < uppers; j++) {
printf("%c", upper[j]);
}
for (int j = 0; j < lowers; j++) {
printf("%c", lower[j]);
}
}
return 0;
}
方法 2:
#include <stdio.h>
int main()
{
char str[1024] = {
0};
while(gets(str)) {
int len = strlen(str);
for (int i = 0; i < len; i++) {
for (int j = 1; j < len - i; j++) {
if (str[j] < str[j - 1]) {
char ch = str[j - 1];
str[j - 1] = str[j];
str[j] = ch;
}
}
}
printf("%s\n", str);
}
return 0;
}
11. 配列参照
int a[2][3]; という定義がある場合、次のオプションの a 配列要素への正しい参照は ( )
A: a[2][0]
B: a[2][3]
Cです。 :a[0 ][3]
D: a[1>2][1]
質問分析:
この質問は主に配列の範囲外アクセスの場合を考慮します。2 次元配列の行と列は 0 から始まります。配列 a の場合、行の添字の最大値は 1、列の添字の最大値は です。 2. オプション D では、1 >2 式の値は 0 であり、これは正しいです。他のオプションには、範囲外の行と列が含まれる可能性があります。A は行が範囲外であることを意味し、B は両方の行が範囲外であることを意味しますと列が範囲外であり、C は列が範囲外であることを示します。
質問の答え:
D
12. 配列参照
i と j は両方とも整数変数であることが知られています。次の式のうち、添字参照 X[i][j] と等価でないものは [多肢選択] ( ) A: ( X [i]
+ j )
B: (X+i)[j]
C: *(X+i+j)
D: ( (X+i)+j)
問題分析:
この問題は 2 次元配列の要素へのアクセスをテストします。選択肢 A が正解です。X[i] は i 番目の行の配列名です。配列名は最初の要素のアドレスを表します。 +j の後の要素は、i 行目の添字が j である要素のアドレスです。全体の逆参照は X[i][j] であり、A は正しいです。オプション B は、[] の優先順位が * よりも高いため、コードは **((x+i)+j) と同等であり、X+i+j の後で境界を越えますが、これは X[i を意味しません。 ][j]、だから間違いです。選択肢 C も明らかに間違っています。D オプションは、2 桁の配列の要素にアクセスするための標準的なポインター形式です。
質問の答え:
BC
13. 文字数統計
質問リンク: OJ リンク
質問分析:
この質問の考え方は、0 から 127 までのさまざまな文字が配列内の assi 値に対応する位置を確実に見つけられるように、最初にサイズ 128 の配列を作成し、見つかった位置を 1 に変更し、最後に配列に値を追加して
文字タイプの質問への答えを取得します。
#include <stdio.h>
int main() {
char arr[501]={
0};
while (scanf("%s",arr) != EOF) {
char*ptr=arr;
int count[128]={
0};
while(*ptr){
int temp=*ptr;//通过Assii码值作为下标找到count数组中对应的位置
count[temp]=1;//将值变为1;
ptr++;
}
int ret=0;
for(int i=0;i<=129;i++){
//遍历相加
ret+=count[i];
}
printf("%d\n",ret);
}
return 0;
}
14. ほとんどの要素
質問リンク: OJ リンク
ヒント:
n == nums.length
1 <= n <= 5 * 104
-109 <= nums[i] <= 109
質問分析:
配列内に n/2 回以上出現する数字があります。0 番目の文字から始めて、それが最も多い数字であると仮定し、同じ数字に遭遇した場合はカウントを +1 し、異なる数字に遭遇した場合はカウントを +1 します。数値の場合、カウントは -1 になります。実際には、それらは互いに消費します。カウントが 0 になると、スペルが完了したことを意味し、次の文字から再びスペルが開始されます。ただし、最終的には、次の文字の数がn/2 より多く出現する数字は大きいため、最後に残った文字でもあります。
例:「23335」はまず2文字から1を数え始め、3に出会ったら-1して残りの「335」からスタートする処理が消費されます。このとき保存されている文字は3ですが、 3 に遭遇した場合は +1、5 に遭遇した場合は -1 としてカウントし、カウントが 0 以外の場合、最後に保存される文字は n/2 を超えた文字になります
。
int majorityElement(int* nums, int numsSize){
int count=1;//记录多数元素的个数与非多数元素出现个数的差
int more=nums[0];//将第一个作为多数元素
int i=1;
for(i;i<numsSize;i++){
if(more==nums[i]){
//下标对应的数为多数元素,则count++
count++;
}
else{
//下标对应的数不是多数元素,则count--
count--;
}
if(count==0){
//如果count等于0,那就可能该数不是多数元素,将下一个作为多数元素继续遍历
more=nums[i+1];
}
}
if(count>0){
//多数元素的个数与非多数元素出现个数的差大于0,则说明此时记录的元素多于总数的一半,为多数元素,
return more;
}
else{
return 0;
}
}
要約する
大事なことは3回言いましょう!
来て!来て!来て!