简体   繁体   English

合并排序 Arrays

[英]Merging Sorted Arrays

I am beginner in C programming.我是 C 编程的初学者。 I have been doing these for hours, but I couldn't produce the needed output.我已经做了几个小时,但无法生成所需的 output。

Input: 1 2 3 4 5 : 6 7 8 9
Output: 1 2 3 4 5 6 7 8 9
Input: 1 3 4 5 6 7 8: 1 2 10
Output: 1 1 2 3 4 5 6 7 8 10
Input: 2 3 9: 1 2 4 5
Output: 1 2 2 3 4 5 9

Basically, the input consist of two arrays separated by a colon.基本上,输入由两个用冒号分隔的 arrays 组成。 I know how to merge and sort them but my problem is that colon.我知道如何合并和排序它们,但我的问题是那个冒号。 So far, here is the code I've created:到目前为止,这是我创建的代码:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int a[100],b[100];
    int i;
    
     printf("Enter elements in array:");

     do 
     {
    scanf("%d", &a[i++]);
     } while(getchar() != ':');

    int size1=i;

    for(i=0; i<size1; i++)
    {
        printf("%d",a[i]);
    }
    
  return 0 ;
}

This works in reading the second and third test case, however, the first one seems to produce numbers it shouldn't.这适用于读取第二个和第三个测试用例,但是,第一个似乎产生了它不应该产生的数字。

Second Test Case第二个测试用例

What should I do?我应该怎么办? Any help would be appreciated, please.请提供任何帮助,我们将不胜感激。 Thank you so much.太感谢了。

Using scanf() isn't necessarily the right tool here.在这里使用scanf()不一定是正确的工具。 The reason is that it does not recognize that your user pressed the Enter key to indicate the end of input.原因是它无法识别您的用户按下Enter键以指示输入结束。

Better to read a line of text, then parse it to an array of whatever type you want.最好读取一行文本,然后将其解析为您想要的任何类型的数组。 You can even use sscanf() in a loop to do it!您甚至可以在循环中使用sscanf()来完成它!

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

int main(void)
{
    // Each array should also have a SIZE (number of elements being used)
    int A[100],     B[100];
    int A_size = 0, B_size = 0;  // Initially, no elements are being used

    // Ask the user for input and get it as a STRING
    printf("Enter arrays (separated by colon): ");
    char s[1000];
    fgets(s, sizeof s, stdin);
    
    // Now we are going to use sscanf() to traipse the string.
    char * p = s;  // `p` is our current position in the string
    int    n = 0;  // `n` is the number of characters last scanned by sscanf()

    sscanf(p, " %n", &n);  // skip any leading whitespace

    // For each successful scan of WHITESPACE INTEGER WHITESPACE:
    //   update the size of A[]
    while (sscanf(p+=n, "%d %n", A+A_size, &n) == 1) A_size += 1;
    if (*p != ':') return 1;  // sscanf() should have failed to read an integer at ':'

    // Prepare for the next loop by scanning past the colon (and eating any whitespace)
    sscanf(p, ": %n", &n);
    
    // For each successful scan of WHITESPACE INTEGER WHITESPACE:
    //   update the size of B[]
    while (sscanf(p+=n, "%d %n", B+B_size, &n) == 1) B_size += 1;
    if (*p) return 1;  // sscanf() should have reached the end of the string
    
    // Let’s print what we got from the user
    printf("A[%d] =", A_size);  for(int i=0; i<A_size; i++) printf(" %d", A[i]);  printf("\n");
    printf("B[%d] =", B_size);  for(int i=0; i<B_size; i++) printf(" %d", B[i]);  printf("\n");

    return 0 ;
}

To be fair, doing stuff like this is tricky as hell.公平地说,做这样的事情非常棘手。 I even wrote an old answer all about using file I/O style functions on a string that explains the mechanism I used here.我什至写了一个关于在字符串上使用文件 I/O 样式函数的旧答案,解释了我在这里使用的机制。

Better, maybe, is to simply tokenize the string and convert its parts.也许更好的方法是简单地标记字符串并转换其部分。

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

int main(void)
{
    int A[100],     B[100];
    int A_size = 0, B_size = 0;

    printf("Enter arrays (separated by colon): ");
    char s[1000];
    fgets(s, sizeof s, stdin);
    
    // Now we are going to tokenize the string. 
    // To do that we first need to split it between A and B:
    char * colon = strchr(s, ':');
    if (!colon) return 1;
    *colon = '\0';
    
    // Now we will use strtok() to get the individual elements of A[]
    for (char *token, *start = s;  (token = strtok(start, " \n\r\t"));  start = NULL)
    {
      // Use any method you like to perform the conversion to int.
      // For this example, I will just use this fictitious helper function:
      A[A_size++] = convert_to_integer(token);
    }
    
    // Rinse and repeat for B[].
    for (char *token, *start = colon+1;  (token = strtok(start, " \n\r\t"));  start = NULL)
    {
      B[B_size++] = convert_to_integer(token);
    }
    
    // Let’s print what we got from the user
    printf("A[%d] =", A_size);  for(int i=0; i<A_size; i++) printf(" %d", A[i]);  printf("\n");
    printf("B[%d] =", B_size);  for(int i=0; i<B_size; i++) printf(" %d", B[i]);  printf("\n");

    return 0 ;
}

While less so, using strtok() is still tricky, so take care.虽然情况并非如此,但使用strtok()仍然很棘手,所以要小心。 I had originally written the loop by punning the token value with start .我最初是通过用start双关语token值来编写循环的。 But then I figured that was likely too confusing.但后来我认为这可能太令人困惑了。 Nevertheless it is a common C idiom you will see.尽管如此,您还是会看到一个常见的 C 习语。

for (char *token = s;  (token = strtok(token, "..."));  token = NULL)
{
  do_something_with(token);
}

The hypothetical convert_to_integer() function is tricky too.假设的convert_to_integer() function 也很棘手。 Not because it is a helper, but because converting a string to integer in C is tricky — all kinds of things can go wrong if input doesn't conform.不是因为它是一个帮助程序,而是因为将字符串转换为 C 中的 integer 是棘手的——如果输入不符合,各种事情都可能 go 出错。 But that is a separate discussion.但那是一个单独的讨论。

To recap:回顾一下:

  1. Get user input as a string (a single line of input)将用户输入作为字符串获取(单行输入)
  2. Attempt to convert user input to your desired data尝试将用户输入转换为您想要的数据

Processing user input as an array has added complexity, but it is not unmanageable.将用户输入作为数组处理增加了复杂性,但并非难以管理。

EDIT: Oh, I should notice to you that I considered empty arrays as valid input.编辑:哦,我应该注意到你我认为空 arrays 作为有效输入。 (You should definitely test your Merge function against one or more argument arrays being empty.) (你绝对应该针对一个或多个参数 arrays 为空来测试 Merge function。)

1 2 3:
:7 9
:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM