Как сгенерировать все отдельные числа, которые могут быть сформированы путем исключения одной или нескольких цифр слева и / или справа от каждого числа - PullRequest
0 голосов
/ 10 января 2019

Мне нужно прочитать некоторые числа из файла и сгенерировать все числа, которые можно сформировать, удалив 1 цифру в начале и одну из конца (для каждого прочитанного числа) и распечатать их в новый файл. Я знаю, как читать и печатать в файлах, поэтому мой вопрос больше о том, как я должен думать при решении этой проблемы. Вот пример для этой проблемы:

для 3457 вывод должен быть:

457
345
34
45
57
3
4
5
7

Первоначально я думал о том, чтобы прочитать числа в виде массива строк с использованием двойного указателя (при условии, что я знаю, сколько чисел мне нужно прочитать, чтобы я мог динамически распределять для него память), а затем поработать с ними.

После этого я подумал о способе генерации чисел, полученных путем удаления 1 цифры с начала и одной с этого конца (но не одновременно), для чего я использовал цикл for:

for ( i = 1, j = (strlen(p[0]) - 2); i < strlen(p[0]) - 2, j >=0; ++i, --j ) //p[0] is my first number read from the file
{
    printf("\n%s", p[0] + i); //this will print the numbers 457, 57, 7

    char temp[10];

    strncpy(temp, p[0], j);//I copy into a new temporary string to print the numbers 345, 34, 3
    temp[j] = '\0';

    printf("%s", temp);
    printf("\n%s", temp + i);//this will print the numbers 45,4





}  

Но я понятия не имею, как поступить с остальными числами, и я просто не смог найти или придумать алгоритм, который будет печатать их в таком порядке, поэтому я был бы очень признателен за помощь в том, как решить эту проблему

Ответы [ 2 ]

0 голосов
/ 10 января 2019

Далее предполагается, что числа считываются из входного файла как строки (символьные массивы с нулевым символом в конце) и что эти строки являются допустимым представлением целых 10 чисел, не обязательно в диапазоне int, только только цифры .

  • Пропустить ведущие нули. Я предполагаю, что строка типа "0042", если она не отклонена, должна интерпретироваться как число 42 , поэтому выходные данные должны быть только 4 и 2 без каких-либо 0. strspn может быть использовано здесь.

  • Найти длину (len) оставшейся строки, если она меньше двух символов, вернуть.

  • Цикл от 1 (входит в комплект) до len (исключается). Это количество символов, которое нужно удалить из источника, назовем его i.

    • Размер подстрок составляет sub_length = len - i.

    • Цикл от 0 до i (оба включены), чтобы рассмотреть все подстроки размера sub_length. Например. с 123 рассмотрим сначала 12 и 23.

      • Если первый символ подстроки равен '0', а его длина больше 1, пропустите следующие шаги, например, например. с 1007 мы не будем печатать 007 или 07, только 0 и 7.

      • Проверьте, можно ли найти фактическую подстроку в левой части исходной строки, которую мы уже рассмотрели. Например. учитывая 4545, после печати 45 и 54 мы найдем последний 45 в 454 и пропустим его. Может пригодиться цикл с такими функциями, как strncmp или memcmp, здесь более чем strstr, для которого в качестве параметров требуются строки с нулевым символом в конце.

      • Если на предыдущем шаге не найдено дубликата, выведите подстроку (с циклом или с использованием printf с указателем формата "%.*s", как объяснено здесь ).

Этот алгоритм даст следующие результаты:

Source: "3457"
345 457 34 45 57 3 4 5 7

Source: "1045"
104 10 45 1 0 4 5

Source: "5454"
545 454 54 45 5 4

Source: "10000"
1000 100 10 1 0

Source: "0042"
4 2
0 голосов
/ 10 января 2019

Предполагая, что у вас есть число, преобразованное в строку (например, с использованием sprintf), вы можете сделать что-то вроде этого:

  • Возьмите оригинальную строку и удалите 0 символов справа

    • Удалите 0 символов слева и напечатайте
    • Удалите 1 символов слева и выведите
    • Удалите 2 символов слева и напечатайте
    • ...
    • Удалить длина строки - 1 символов слева и вывести
  • Возьмите оригинальную строку и удалите 1 символов справа

    • Удалите 0 символов слева и напечатайте
    • Удалите 1 символов слева и напечатайте
    • Удалите 2 символов слева и напечатайте
    • ...
    • Удалить длина строки - 1 символов слева и вывести
  • Возьмите оригинальную строку и удалите 2 символов справа

    • Удалите 0 символов слева и напечатайте
    • Удалите 1 символов слева и напечатайте
    • Удалите 2 символов слева и напечатайте
    • ...
    • Удалите длина строки - 1 символов слева и выведите

Вышеуказанное легко реализовать, используя два вложенных цикла for. Как:

int main()
{
  char str[] = "123456";
  size_t len = strlen(str);
  size_t i, j;
  for (i = 0; i < len; i++) // i is number of chars to remove (aka not print) from right
  {
    for (j = 0; j < len-i; j++) // j is number of chars to remove (aka not print) from left
    {
      size_t z=j;
      int p = 0;
      while (z < (len - i))
      {
        printf("%c", str[z]);
        z++;
        p = 1;
      }
      if (p) printf("\n");
    }
  }
  return 0;
}

Выход:

123456
23456
3456
456
56
6
12345
2345
345
45
5
1234
234
34
4
123
23
3
12
2
1

Теперь, если входная строка «1001», вывод программы (комментарии добавлены вручную):

1001  // ok
001   // Is this valid? Or should it be 1
01    // Is this valid? Or should it be 1
1     // ok
100   // ok
00    // Is this valid? Or should it be 0
0     // ok
10    // ok
0     // ok but repeated! Is this valid?
1     // ok but repeated! Is this valid?

Как вы видите, может быть проблема с алгоритмом, например, ведущий ноль и повторяющиеся числа. Если это неверно, вам нужно будет

  1. отслеживать уже напечатанные номера
  2. избегайте печати начальных нулей
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...