簡體   English   中英

C 語言在輸入的詞中查找T或t

[英]C language finding T or t in the entered word

您有興趣查找在單詞的前半部分包含字母“t”或“T”的單詞(如果有的話,包括中間字母)。 具體來說,如果單詞的前半部分確實包含“t”或“T”,則您的程序應該 output a 1。如果前半部分不包含字母“t”或“T”,但后半部分包含,那么你的程序應該是 output a 2。否則,如果單詞中根本沒有 't' 或 'T',你的程序的 output 應該是 -1。 您可以假設輸入的單詞不超過 50 個字母。

 #include <stdio.h>
int main (void){
    int i=0;
    char word[51];
    int l=0;
    int half;
    char found1='T';
    char found2='t';
    
    
    scanf("%s",word);
    while (word[i]!='\0'){
        i++;
        
    }
    half=i/2;
    while(word[l]!='\0'){
         scanf("%s",word);
         l++;
        if((word[l]!=half)&&((word[l]==found1)&&(word[l]==found2))){
            printf("1");
        }
    if((word[l]!=i)&&((word[l]==found1)&&(word[l]==found2))&&(word[l]>=half)){
        printf("2");
    }
    }
    if(i%2!=0){
        printf("1");
    }else{
        printf("-1");
    }
    return 0;
}

盡可能簡單地分解它:


在字符串中查找Tt的索引。

你找到了嗎?

  • 不,output 0然后退出

上半年找到了嗎?

  • 不,output 2然后退出

Output 1並退出。


獲取輸入:

char word[52];
fgets(word, sizeof(word), stdin);

使用以下命令確定字符串的長度:

int n = strlen(word) - 1;  // Don’t count the '\n' at the end of the input

請記住 integer 除法向零舍入,因此:

int half = (n + 1) / 2;

任何< half都在上半場。 任何 half都在下半場。

考慮一個沒有#include 的 C 程序可能是有益的。

int main(int argc, char *argv[])
/*
* Assume the input word is argv[1], empty word (not containing T) if
* no argument.  The result is in the return value of the main
* function, so we don't need to include stdio to print it.
*/
{
    if (argc < 2)
        return -1; // no T

    char *word = argv[1];

    int found = -1, length = 0, ch;
    while ((ch = *(unsigned char*)word++) != 0)
    {
        ++length;
        if (found < 0 && (ch == 't' || ch == 'T'))
            found = length;
    }

    if (found < 0)
        return -1; // no T

    return 2*(found -1) < length? 1: 2;
}

測試時, -1顯示為255

$ gcc -W -Wall -g so.c
$ ./a.out t; echo $?
1
$ ./a.out o; echo $?
255
$ ./a.out to; echo $?
1
$ ./a.out oto; echo $?
1
$ ./a.out ot; echo $?
2

但是,非 ASCII 字符無法按預期工作。 下面,參數的第一個字符是hwair ,在 UTF-8 編碼中占四個字節:

$ ./a.out 𐍈tooo; echo $?
2

檢測兩件事就足夠了:

  • 單詞的長度。

  • 第一個tT的偏移量。

“單詞”不需要存儲,只需檢測其結尾即可。
無需小 (50) 個字母限制。

  #include <ctype.h>
  #include <stdio.h>

  int main() {
    unsigned long long word_length = 0;
    unsigned long long t_offset = 0;  // First letter in a word is at offset 1.
    int ch;
    
    do {
      ch = getchar();
      if (isalpha(ch)) {
        word_length++;
        if ((ch == 't' || ch == 'T') && (t_offset == 0)) {
          // Record offset of first "Tee".
          t_offset = word_length;
        }
      } else {
        // Detect end-of-word
        if (word_length > 0) {  
          const char *output = "-1";
          if (t_offset > 0) {
            if (t_offset <= (word_length+1)/2) output = "1";
            else output = "2"; 
          }
          puts(output);
          word_length = 0;
          t_offset = 0;
        }
      }
    } while (ch != EOF);
  }

雖然您可以逐個字符地進行比較,但 C 提供了char *strpbrk(const char *s, const char *accept) ,它將在s中提供第一個字節(字符)的 position accept 使用"Tt"作為您的acceptword作為s您會收到指向word中第一次出現'T''t'的指針,例如

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

#define MAXWORD 51

int main (void) {
  
  char word[MAXWORD], *ptr2t = NULL;  /* storage and ptr to t or T */
  size_t len = 0, pos = 0, mid = 0;   /* word len, tT pos & mid pos */
  
  fputs ("\nenter word (50 char max): ", stdout);   /* prompt */
  
  if (!fgets (word, MAXWORD, stdin)) {      /* read up  to 50 chars */
    puts ("(user canceled input)");
    return 0;
  }
  word[(len = strcspn (word, "\n"))] = 0;   /* save len, trim \n from end */
  
  if (!(ptr2t = strpbrk (word, "Tt"))) {    /* locate 't' or 'T' in word */
    puts ("-1");
    return 0;
  }
  
  if (len == 1) {   /* if length 1, no determination of half is possible */
    puts ("(length is 1, half determination not possible)");
    return 0;
  }
  
  mid = len / 2;                  /* get mid position */
  pos = ptr2t - word;             /* get postion in word */
  
#ifdef ODD_MID_IN_1ST             /* if considering mid character in odd */
  if (len & 1) {                  /* length part of 1st half, add 1 to  */
    mid += 1;                     /* mid.                               */
  }
#endif

  puts (pos < mid ? "1" : "2");   /* output 1 in 1st half, 2 otherwise. */
}

根據我的評論,您還必須處理輸入長度為1的情況,因為不能確定一半(根據需要處理),並且您必須確定奇數長度單詞中中間字符的哪一半屬於。默認情況下,中間字符屬於下半部分。 定義ODD_MID_IN_1ST將更改行為以將中間字符放在上半部分(由您決定)。

編譯

使用gcc ,您可以使用:

gcc -Wall -Wextra -pedantic -Wshadow -std=c11 -Ofast -o bin/tin1sthalf tin1sthalf.c

其中選項-Wall -Wextra -pedantic -Wshadow啟用完整警告(大部分)並檢查是否有陰影變量。 -std=c11指定語言標准為 C11, -Ofast是針對 gcc >= 4.6 的完全優化,在此之前優化級別僅限於O0O1O2O3 添加-Werror以將警告視為錯誤(推薦)。 可執行文件 output -o將放置在bin/目錄中(根據需要更改)。

始終在啟用完全警告的情況下進行編譯(每個編譯器都提供啟用警告的選項)並且在沒有警告的情況下編譯之前不要接受代碼( -Werror防止你作弊......)

示例使用/輸出

顯示程序的各種特殊情況處理和一般 output:

$ ./bin/tin1sthalf

enter word (50 char max): t
(lenght is 1, half determination not possible)

$ ./bin/tin1sthalf

enter word (50 char max): t_
1

$ ./bin/tin1sthalf

enter word (50 char max): _t
2

$ ./bin/tin1sthalf

enter word (50 char max): _t_
2

$ ./bin/tin1sthalf

enter word (50 char max): ___
-1

$ ./bin/tin1sthalf

enter word (50 char max): _T__
1

$ ./bin/tin1sthalf

enter word (50 char max): __t_
2

有很多很多方法可以解決這個問題。 如果他們遵守語言標准或 POSIX 標准(如果適用),那么沒有人比其他人更有權利。 唯一的區別是效率之一。 當你學習編碼時,你的重點應該放在讓代碼運行上,而不是過早地擔心微優化。 一旦您的整個程序都可以運行,然后對其進行概要分析並擔心此時的代碼優化。

如果您有任何疑問,請告訴我。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM