Строка, числа и скобки

212
15 декабря 2016, 16:15

![alt text][1]На вход подается что-то типа: (12 32(32 12)).
Мне считать скобки перед числом, увидев число, выполнить: res=a[i]*(0.5)^(b[i]), где a[i] — это какое-то число из строки ввода, b[i] — скобочный итог к моменту, и соответсвенно суммировать такие результаты до конца строки.

Вот пример моей программы, но она возводит в степени не числа, а цифры (т.е. делит каждое число на цифры):

    using namespace std;
int main() {
    string str, st;
    int index = 0, k = 0, ind = 0, index1 = 0,s = 0;
    long double  res = 0;
    char chr;
    getline(cin, str);
    while (index < str.length())
    {
        chr = str[index];
        if ((chr == '1') || (chr == '2') || (chr == '3') || (chr == '4') || (chr == '5') || (chr == '6') || (chr == '7') || (chr == '8') || (chr == '9') ||(chr=='0') )
        {
            while ((str[index] == '1') || (str[index] == '2') || (str[index] == '3') || (str[index] == '4') || (str[index] == '5') || (str[index] == '6') || (str[index] == '7') || (str[index] == '8') || (str[index] == '9')|| (str[index] == '0'))
            {
                st[ind] = str[index];
                index1 = index;
                ind++;
                index++;
            }
            k = atoi(st.c_str()); cout<<"k="<<k<<" ";
            res = res + k*pow(0.5, s); cout<<"res"<<res<<endl;
            index = index1;
            ind = 0;
        }
        chr = str[index];
            if (chr == '(')
            {
                s = s + 1;
            }
            if (chr == ')')
            {
                s = s - 1;
            }
            st.clear();
std::cout << (st.empty() ? "YES" : "NO") << endl;
        index++;
    }
    cout << round(res * 100) / 100.;
    system("pause");
}

Пишет, что строка st, очищается, а на тестах иногда добовляет в конец цифры из предедущей строки.
Например (3332 554) выдает второе число как 5542, вместо 554.

Answer 1

С первой встретившейся цифры, до тех пор пока встречаются цифры, записывайте их в строку, когда встретите не цифру, вызываете atoi, получаете число, очищаете строку и т.д.

UPDATE

http://ideone.com/XdNwhF

P.S. Это очень простая задача и не справляться с таким это плохо, на вашем этапе советую порешать алгоритмические задачки самостоятельно, чтобы набраться опыта, например, тут acmp.ru, сам когда-то таким был.

Обновление

Проблема в том, что нельзя в string в с++ добавлять символы с помощью оператора []. То, что компилятор на это не ругается, это как раз один из способов выстрелить себе в ногу, как часто говорится.

st[ind] = str[index];

Вот в этой строке ошибка. Это ведет к такому поведению. Почему так происходит? Когда вы только создаёте переменную, её длина равна 0. Добавляя в неё символы с помощью оператора [], предположу, что длина так и остаётся равна 0. Вы можете это проверить, добавив отладочный вывод до и после st.clear().

Если делать так:

cout << "st:" << st << endl;
st.clear();
cout << "st_clear:" << st << endl;

то вам выведет

st: st_clear:

То есть оба вывода выведут пустую строку, в то время как

cout << "st:" << st.c_str() << endl;
st.clear();
cout << "st_clear:" << st.c_str() << endl;

выведет на вашем примере

st:3332 st_clear:5542

По сути, в вашем случае st.clear() не очищает строку, поскольку её длина и так 0. При этом в память по этому адресу при использовании оператора [] пишутся цифры все равно. Надеюсь, понятно объяснил.

Answer 2

@doomsday: "Я не понимаю, откуда она берется. Ведь строка пуста."

Глядя на программу в вопросе, не очевидно, правильно ли она манипулирует индексы index, index1, ind, что может вызывать ошибку. Можно посмотреть в отладчике (таком как gdb) на значения индексов с вводом, который ведёт к ошибке, чтобы убедиться, что индексы имеют ожидаемые значения, или можно переписать эту программу, не используя индексы вообще:

#include <stdint.h> /* uintmax_t */ 
#include <stdio.h>
#include <stdlib.h> /* EXIT_FAILURE */
int main(void) {
  long double sum = 0.0; /* result */
  uintmax_t depth = 0, /* how deep parens are nested */
    number = 0; /* the current number */
  int c;
  while ((c = getchar()) != EOF) {
    if ('0' <= c && c <= '9') 
      number = 10*number + (c - '0'); /* build number from digits */
    else { /* not a digit */
      /* result += a[i] * (0.5)**(b[i]) */
      sum += (long double)number / (1U << depth); /* number >> depth */
      number = 0; /* reset number */
      if (c == '(')
        ++depth; 
      else if (c == ')') {
        if (depth == 0) exit(EXIT_FAILURE);
        --depth;
      }
    }
  }
  if (printf("%Lf\n", sum) < 0)  exit(EXIT_FAILURE);
  return feof(stdin) ? EXIT_SUCCESS : EXIT_FAILURE;
}

Для краткости не приведены сообщения об ошибке и обработка ошибок переполнения, потери точности.

Исполняемый пример.

READ ALSO
Как обратиться к элементу вектора в ассемблерной вставке?

Как обратиться к элементу вектора в ассемблерной вставке?

Как обратиться к элементу вектора в ассемблерной вставке c++ (vs2012)?

226
Run-Time Check Failure #3 - The variable &#39;x&#39; is being used without being initialized

Run-Time Check Failure #3 - The variable 'x' is being used without being initialized

Пишу программуКод, та часть на которой ломается:

237
Считывание строки из файла и дальнейшая работа со следующей по счету строкой

Считывание строки из файла и дальнейшая работа со следующей по счету строкой

Название, может, криво написал, лучше опишу задание

187
Модификаторы функций и их отсутвие в языковом стандарте

Модификаторы функций и их отсутвие в языковом стандарте

Почему в реализации компилятора есть функции с обратным вызовом с модификаторами (например APIENTRY, PASCAL и тд

256