Member 13926094 Ответов: 4

Хотел бы знать, какую ошибку я совершил


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

Цель состоит в том, чтобы сформировать максимально возможное время в формате HH:MM:SS, используя любые шесть из девяти заданных однозначных цифр (не обязательно различимых)

Учитывая набор из девяти одиночных (не обязательно различных) цифр, скажем 0, 0, 1, 3, 4, 6, 7, 8, 9, можно сформировать много различных времен в 24-часовом формате времени чч:мм:СС, например 17:36:40 или 10:30:41, используя каждую из цифр только один раз. Цель состоит в том, чтобы найти максимально возможное допустимое время (с 00:00:01 до 24:00:00), которое может быть сформировано с использованием примерно шести из девяти цифр ровно один раз. В данном случае это 19:48:37.

Поэтому я пробовал писать код, но это всегда приводит к ошибке во время выполнения. Любая помощь будет оценена по достоинству

Что я уже пробовал:

#include<stdio.h>
int main()
{
    int a[8],b[5],i,c=0,d;
    for(i=0;i<9;i++)
    {
        scanf("%d",&a[i]);
        if(a[i]==0)
        c++;
    }
    for(i=8;i>=0;i++)
    {
        if(a[i]<3)
        {
            b[0]=a[i];
            if(b[0]==1||b[0]==0)
            {
                b[1]=a[8];
                a[8]=-1;
            }
            else
            {
                i=8;
                while(a[i]>=5)
                {
                    i--;
                }
                if(a[i]==4&&c==4)
                {
                    b[1]=4;
                    b[2]=0;
                    b[3]=0;
                    b[4]=0;
                    b[5]=0;
                    a[0]=-1;a[1]=-1;a[2]=-1;a[3]=-1;
                }
                else
                {
                    while(a[i]==4)
                    {
                        i--;
                    }
                    b[1]=a[i];
                    a[i]=-1;
                }
                
            }
            
        }
        else
        printf("Impossible");
    }
    for(i=8;i>=0;i++)
    {
        if(a[i]<6)
        {
            d=i;
        }
        else
        printf("Impossible");
    }
    for(i=d;i>=0;i--)
    {
        if(a[i]!=-1)
        {
            b[2]=a[i];
            a[i]=-1;
            break;
        }
    }
    for(i=d;i>=0;i--)
    {
        if(a[i]!=-1)
        {
            b[4]=a[i];
            a[i]=-1;
            break;
        }
    }
    for(i=8;i>=0;i--)
    {
        if(a[i]!=-1)
        {
            b[3]=a[i];
            a[i]=-1;
            break;
        }
    }
    for(i=8;i>=0;i--)
    {
        if(a[i]!=-1)
        {
            b[5]=a[i];
            a[i]=-1;
            break;
        }
    }
    printf("%d%d:%d%d:%d%d",b[0],b[1],b[2],b[3],b[4],b[5]);
    
    
}

Patrice T

Какая ошибка времени выполнения, где ?

Patrice T

В последний раз, когда я проверял, 24 - часовое время работало с 00:00:00 до 23:59:59.

4 Ответов

Рейтинг:
1

Patrice T

Сообщение об ошибке может быть вызвано тем, что a и b неправильный размер:

int a[8],b[5],i,c=0,d;

В противном случае ваш алгоритм просто ошибочен, весь logc ошибочен, используйте отладчик, чтобы увидеть, что происходит, и обратите внимание на используемые цифры.

Ваш код ведет себя не так, как вы ожидаете, или вы не понимаете, почему !

Существует почти универсальное решение: запускайте свой код на отладчике шаг за шагом, проверяйте переменные.
Отладчик здесь, чтобы показать вам, что делает ваш код, и ваша задача-сравнить с тем, что он должен делать.
В отладчике нет никакой магии, он не знает, что вы должны делать, он не находит ошибок, он просто помогает вам, показывая, что происходит. Когда код не делает того, что ожидается, вы близки к ошибке.
Чтобы увидеть, что делает ваш код: просто установите точку останова и посмотрите, как работает ваш код, отладчик позволит вам выполнять строки 1 на 1 и проверять переменные по мере их выполнения.
Отладчик - Википедия, свободная энциклопедия[^]

Освоение отладки в Visual Studio 2010 - руководство для начинающих[^]
Базовая отладка с помощью Visual Studio 2010 - YouTube[^]
1.11 — отладка программы (пошаговое выполнение и останова) | выучить C++[^]
Отладчик здесь только для того, чтобы показать вам, что делает ваш код, и ваша задача-сравнить его с тем, что он должен делать.

PS: этот код кажется мне знакомым, вы уже разместили его в более старом вопросе ?


Member 13926094

Спасибо за предложение я буду иметь это в виду

Рейтинг:
1

CPallini

Следующая программа должна выполнить эту работу.
Пожалуйста, обратите внимание:

  • Он не находит особого случая 24:00:00 вы (оставлено в качестве упражнения) должны обращаться с ним явно
  • Он идет O(2) с входными сигналами (т. е. доступными только для небольших входных последовательностей)


#include <stdio.h>

#define INPUT_DIGITS  9
#define ITEMS 3

void swap(unsigned int * pa, unsigned int *pb)
{
  unsigned int temp = *pa;
  *pa = *pb;
  *pb = temp;
}

// finds the pair of digits giving maximum number less than (or equal to) limit.
// swaps them with the two ending items and eventually returns the found maximum
int find_max(unsigned int limit, unsigned int a[], size_t size)
{
  unsigned int max = 0;
  size_t index[2] = {size, size};
  size_t i, j;
  for ( i=0; i<size; ++i)
  {
    for (j=0; j<size; ++j)
    {
      if ( i == j) continue;
      unsigned int n = a[i]*10+a[j];
      if ( max <= n && n <= limit)
      {
        max = n;
        index[0] = i;
        index[1] = j;
      }
    }
  }
  if ( index[0] == size) return -1; // failure: not found

  // double swap
  swap( &a[index[0]], &a[size-1]);
  if ( index[1] == (size-1) )
    index[1] = index[0]; // this handles a very corner case
  swap( &a[index[1]], &a[size-2]);

  return max;
}

int main()
{
  unsigned int limit_array[ITEMS] = {23, 59, 59}; // limits for hours, minutes, seconds
  size_t i;
  unsigned int a[INPUT_DIGITS];
  int result[ITEMS];

  for (i=0; i<INPUT_DIGITS; ++i)
  {
    if ( scanf("%u", &a[i]) != 1)
      return -1; // invalid input
  }

  for (i=0; i<ITEMS; ++i)
  {
    size_t size = INPUT_DIGITS - (i*2);
    result[i] =  find_max( limit_array[i], a, size );
    if ( result[i] == -1)
      return -1; // not found
  }

  for (i=0; i<ITEMS; ++i)
  {
    printf("%d", result[i]);
    if (i != 2)
      printf(":");
  }
  printf("\n");

  return 0;
}


Patrice T

В последний раз, когда я проверял, 24 - часовое время работало с 00:00:00 до 23:59:59. :)

CPallini

В самом деле, мы основываемся на 0, моя дорогая.

Рейтинг:
0

OriginalGriff

Я не пробираюсь через этот код: читать его противно.
Сделайте себе одолжение, и начните с написания кода, который предназначен для чтения.
Те средства:
1) комментарии, где это применимо, чтобы объяснить, что делает код. Это не объясняет саму строку кода, но скажите мне, почему он делает то, что делает.

if(a[i]<3)
Почему я заинтересован в значение, которое меньше, чем три? Так что, если так? Что ты собираешься с ним делать? Хорошо, я могу догадаться, что вы пытаетесь - правильно - отделить самую высокую цифру часа ... но вы должны рассказать людям!
2) прекратите использовать однобуквенные имена переменных. Используйте имена, которые описывают назначение переменной, и код начнет сам себя документировать. Это может быть дольше печатать, но это намного безопаснее и легче понять - не очевидно, что "b" должно было быть "a", но если Вы читаете с "output" вместо "input", то это явно неправильно!
3) последовательно отступайте и - как новичок - всегда используйте пары "{" и"}", даже если они не нужны.
int a[8],b[5],i,c=0,d;
for(i=0;i<9;i++)
{
    scanf("%d",&a[i]);
    if(a[i]==0)
    c++;
}
Отступ подразумевает, что c++; выполняется независимо от значения a[i] и это не тот случай. И пока мы здесь, почему являются вы приращением c только когда пользователь вводит ноль?
4) разбейте код на функции, чтобы вы могли тестировать их изолированно и быть уверенными, что каждая функция делает то, что вы намеревались сделать в изоляции - вы можете вызвать функции из вашего основного кода, и все это снова станет более читаемым. И гораздо проще модифицировать!

Когда вы это сделаете, начните работать над тем, почему это не удается - это ваша домашняя работа, поэтому это часть вашей задачи, чтобы заставить ее работать, а не моя. :смеяться:
К счастью, у вас есть инструмент, который поможет вам выяснить, что происходит: отладчик. Как вы его используете, зависит от вашей компиляторной системы, но быстрый поиск в Google имени вашей IDE и "отладчика" должен дать вам необходимую информацию.

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

Извините, но мы не можем сделать это за вас - пришло время вам освоить новый (и очень, очень полезный) навык: отладку!


Member 13926094

1&2) Я понимаю, что однозначные переменные не имеют никакого смысла, когда кто-то читает его, но я никогда не предполагал, что буду публиковать его в первую очередь, поэтому я не изменил переменные. Извините.
3) я увеличивал c так, чтобы знать, сколько зеор присутствует во входных данных. Поэтому для случая 24 часа мне нужно было проверить, есть ли 4 Зеора, которые могут следовать за 24 часами. если нет, то мне придется изменить время на 23 часа, так как 24 часа+ минуты не подходят.
4) понятно, я попробую это сделать. И я не хотел, чтобы кто-то заставлял этот код работать. Я просто хотел знать, почему логика даже не реагирует на входные сигналы. Если бы были выходы, я бы работал с ним, чтобы выяснить ошибку, но Ошибка времени выполнения-это что-то новое для меня, поэтому я подумал о том, чтобы обратиться за помощью. Поскольку вы сказали мне, что я не могу надеяться найти ответы на что-то настолько приземленное, я буду избегать публикации таких вопросов.
И я буду использовать отладчик для моих будущих кодов. Большое спасибо за вашу помощь.

OriginalGriff

Это не случай "не могу надеяться найти ответы на что-то настолько приземленное", это то, что вам нужно узнать, и гораздо, гораздо лучше узнать это на простых проектах, подобных этому, а не ждать, пока у вас будет 500 000 строк бегемота и не иметь понятия, с чего начать!

И вы всегда должны исходить из того, что код должен быть читабельным - ведь вам может понадобиться изменить его через пару месяцев, когда вы его полностью забудете! :смеяться:

Рейтинг:
0

Jochen Arndt

У вас есть доступ к массивам вне привязки для ваших массивов a и b.

Ваш массив a имеет размер 8. Затем вы можете получить доступ к его элементам, используя индексы от 0 до 7 (Длина минус один). Похожие на b где допустимые индексы находятся в диапазоне от 0 до 4.

При использовании переменной может возникнуть еще один выход за пределы привязки d который может иметь неопределенное значение (вы печатаете "невозможно", но продолжаете выполнение).

Так что используйте что-то вроде этого:

int a[9], b[6];

// ...

if(a[i]<6)
    d=i;
else
{
    printf("Impossible");
    return 1;
}


Я больше не проверял ваш код. Это означает, что ваш код все еще может работать не так, как ожидалось после исправления вышеизложенного из-за логических ошибок.


Member 13926094

Ах, я перепутал размер массива. Я постараюсь исправить это и проверить результат. Спасибо.