Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.53/89: Рейтинг темы: голосов - 89, средняя оценка - 4.53
 Аватар для perec200
0 / 0 / 0
Регистрация: 04.10.2014
Сообщений: 98

Калькулятор с парсингом ввода

04.10.2014, 13:05. Показов 18031. Ответов 78
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет, не так давно начал постигать c++. Возник вопрос как сделать программу-калькулятор, в которую можно вводить свои числа и арифметические операции.
Пример:
Выскакивает консолька и пользователь вводит "17 + 19 * 6 - 8", то есть пользователь не ограничен в действиях.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
04.10.2014, 13:05
Ответы с готовыми решениями:

Простой калькулятор и калькулятор с парсингом
Ребят я совсем не давно только начал изучать сишку, решил написать простенький калькулятор который работает с 2 числами. Возник вопрос, как...

Калькулятор с парсингом строки
Добрый день, дорогие программисты помогите написать калькулятор. Я ввожу строку например 5+8/7*10 и он должен посчитать. Нужно числа...

Калькулятор с парсингом арифметических выражений
Народ интересует вопрос возможно ли сделать калькулятор в console приложении на C++ так что бы я ввожу строку например 3+4*2 он берет всю...

78
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
05.10.2014, 10:00
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от castorsky Посмотреть сообщение
Там, где отсутствует итерация (рекурсия преобразуется в цикл).
Бред, кобыла отдыхает. Попробуйте в цикле разложить матрицу произвольного порядка и все получающиеся при этом миноры от третьего порядка и выше разложить на миноры первой строки. Рекурсивно это делается элементарно, а иттеративно не получится не только запрограммировать, но и вручную разложить так матрицу четвёртого порядка. Третьего раскладыватеся, а матрицы начиная с четвёртого порядка и выше без рекурсии на миноры второго порядка не раскладываются в принципе. При этом в каждом рекурсивно вызванном экземпляре внутри используется именно цикл, без него матрица произвольного порядка не раскладывается даже на старшие миноры.

Добавлено через 3 минуты
Цитата Сообщение от castorsky Посмотреть сообщение
Ведь можно while(*string_ptr){switch(*string_ptr) {...}}
Нельзя.

Добавлено через 2 минуты
Цитата Сообщение от IGPIGP Посмотреть сообщение
Технически, рекурсия проще построения дерева выражений.
Нет. Рекурсия и есть способ построения дерева выражений.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
05.10.2014, 12:38
Цитата Сообщение от taras atavin Посмотреть сообщение
Рекурсия и есть способ построения дерева выражений.
Если выражение - рекурсивный тип, то и в цикле можно же? Хотя рекурсивные алгоритмы в принципе проще и компактнее. Я как раз не спорю.
Мне интересно как ответить TC... Ведь если окажется, что и он писал подобное на других языках, то в чём вопрос? А если нет, то наверное не стоит ставить такую задачу на старте.(имхо)

Не по теме:

А то вчерасегодня среди ночи, порезвился так, что забавно и читать.:D
Дошли до целесообразности изучения С++:scratch:
:)

0
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
05.10.2014, 13:06
Цитата Сообщение от IGPIGP Посмотреть сообщение
Хотя рекурсивные алгоритмы в принципе проще и компактнее.
Попробуйте не рекурсивно найти узел дерева. Рекурсивно пожалуйста.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
TNode *Find(TNode *Root, int Data)
{
 TNode Temp;
 if (Root==NULL)
 {
  return NULL;
 }
 if (Root->Data==Data)
 {
  return Root;
 }
 Temp=Find(Root->Left, Data);
 if (Temp!=NULL)
 {
  return TEMP;
 }
 return Find(Root->Right, Data);
}
. Компактней уже некуда, тем более проще. А нерекурсивно и громоздко и сложней некуда. Или обход дерева.
C++
1
2
3
4
5
6
7
8
9
void Out(TTree *Root)
{
 if (Root!=NULL)
 {
  Out(Root->Left);
  std::cout<<Root->Data;
  Out(Root->Right);
 }
}
. Ну ка сведи к циклу. Дико сомневаюсь, что хватит всех когда либо произведённых носителей, чтоб разместить этого монстра. Да и сложность будет выше крыши. Другой пример - вычисление факториала.
C++
1
2
3
4
5
6
7
8
unsigned long int factorial(unsigned short int n)
{
 if (n==0)
 {
  return 1;
 }
 return n*factorial(n-1);
}
. Сложновато, хоть и компактно, но рекурсивно.
C++
1
2
3
4
5
6
7
8
9
unsigned long int factorial(unsigned short int n)
{
 unsigned short int r;
 for (r=0; n>0; --n)
 {
  r*=n;
 }
 return n;
}
. Проще, больше, не рекурсивно.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
05.10.2014, 13:36
Цитата Сообщение от taras atavin Посмотреть сообщение
Попробуйте не рекурсивно найти узел дерева. Рекурсивно пожалуйста.
Цитата Сообщение от IGPIGP Посмотреть сообщение
Я как раз не спорю.
Дык, я и вступил в тему, защищая рекурсивные алгоритмы. Даже при обходе рекурсивных типов они компактнее и быстрее.
0
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
05.10.2014, 13:47
Не даже, а именно. Рекурсия бывает и неуместна.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
double det(dpuble *a, int n)
{
 double ***minors;
 double result;
 int m;
 int i;
 int j;
 if (n==2)
 {
   return (a[0][0]*a[1][1]-a[1][0]*a[0][1];
 }
 minors=new double**[n];
 for (result=0.0, m=0; m<n; ++m)
 {
  minors[m]=new double*[n-1];
  for (i=0, i<(n-1); i++)
  {
   minors[m][i]=new double[n-1];
   for (j=0, j<(n-1); j++)
   {
    if (i<m)
    {
     minors[m][i][j]=a[i][j+1];
    }
    else
    {
     minors[m][i][j]=a[i-1][j+1];
    }
   }
   if (i%2==0)
   {
    result+=det(minors[m], n-1);
   }
   else
   {
    result-=det(minors[m], n-1);
   }
   delete [] minors[m][i];
  }
  delete [] minors[m];
 }
 delete [] minors;
 return result;
}
void kramer(double **a, int n, double *b, double *x)
{
 double **ax;
 double d;
 double dx;
 int i;
 int j;
 int k;
 d=det(a, n);
 ax=new double*[n];
 for (i=0; i<n; ++i)
 {
  ax=new double [n];  
  for (j=0; j<n; ++j)
  {
   ax[j]=new double [n];  
   for (k=0; k<n; ++k)
   {
    if (i==j)
    {
     ax[j][k]=b[k];
    }
    else
    {
     ax[j][k]=a[j][k];
    }
   }
   dx=det(ax,n);
   x[i]=dx/d;
  }
  for (j=0; j<n; ++j)
  {  
   delete [] ax[j];
  }
 }
 delete [] ax;
}
Сложно, громоздко, рекурсивно.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
double det(double **a, int n)
{
 int i;
 int j;
 int k;
 double r;
 for (i=0; i<n; ++i)
 {
   for (j=i+1; j<n; ++j)
   {
    for (k=i+1; k<n; ++k)
    {
     a[j][k]-=a[i][k]*a[j][i]/a[i][i];
    }
    a[j][i]=0.0;  
   }
 }
 for (r=1.0, i=0; i<n; ++i)
 {
  r*=a[i][i];
 }
 return r;
}
. Просто, компактно, не рекурсивно.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
05.10.2014, 14:35
Цитата Сообщение от taras atavin Посмотреть сообщение
Не даже, а именно. Рекурсия бывает и неуместна.
Просто святые слова. Причём, вместо слова "рекурсия" можно подставить любое содержательное выражение.
Даже видов траверсов деревьев их вон аж целых несколько. Но всё же от цели обхода зависит и от логики выбора следующей рекурсивной ветви. Если дерево не двоичное, а многая-многая-ичное и логика выбора не одно сравнение, а цель - все имеющиеся узлы? Делаем, например, список аналогичный списку подвыражений, - добавляем туда корень и в цикле обходим по узлам одного уровня, купируя на листьях. 5-6 строчек.
Вообще, тема ушла куда-то от калькуляторов.
Так часто бывает. Просит человек строку на гласные и согласные раскидать... И по вопросу и по включаемым файлам видно, что нужно руками сделать и чтобы он понял, а появляются ответы на 2 строчки в которых половина STL.
А я думаю, если человек просит STL то тогда уже, как говорили древние вавилоняне: - "Итератор в руки, бэкинсёртер - в спину, и вперёд!"
А иначе зачем?
1
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
05.10.2014, 14:55
Цитата Сообщение от IGPIGP Посмотреть сообщение
Даже видов траверсов деревьев их вон аж целых несколько. Но всё же от цели обхода зависит и от логики выбора следующей рекурсивной ветви. Если дерево не двоичное, а многая-многая-ичное и логика выбора не одно сравнение, а цель - все имеющиеся узлы? Делаем, например, список аналогичный списку подвыражений, - добавляем туда корень и в цикле обходим по узлам одного уровня, купируя на листьях. 5-6 строчек.
Вообще, тема ушла куда-то от калькуляторов.
Да без проблем.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void Searhc(TDirrectrory *Dirrectrory, TDirrectroryArray &Array, std::string Name)
{
 Dirrectrory *Child;
 if (Dirrectrory!=NULL)
 {
  if (Dirrectory->Name==Name)
  {
   Array+=Dirrectory;
   if (Dirrectory->ChildrenCount>0)
   {
    for (Child=Dirrectory->Children+Dirrectory->ChildrenCount-1; Child>=Dirrectory->Children; --Child)
    {
     Search(Child, Array, Name);
    }
   }
  }
 }
}
. Ну ка избавьтесь здесь от рекурсии.
0
 Аватар для castorsky
1978 / 1082 / 87
Регистрация: 29.11.2013
Сообщений: 3,353
05.10.2014, 15:07
Цитата Сообщение от taras atavin Посмотреть сообщение
Бред, кобыла отдыхает. Попробуйте в цикле разложить матрицу произвольного порядка и все получающиеся при этом миноры от третьего порядка и выше разложить на миноры первой строки. Рекурсивно это делается элементарно, а иттеративно не получится не только запрограммировать, но и вручную разложить так матрицу четвёртого порядка. Третьего раскладыватеся, а матрицы начиная с четвёртого порядка и выше без рекурсии на миноры второго порядка не раскладываются в принципе. При этом в каждом рекурсивно вызванном экземпляре внутри используется именно цикл, без него матрица произвольного порядка не раскладывается даже на старшие миноры.
Не зря меня предупреждали про Ваши проблемы с логикой. Я напомню, ТС парсит простое математическое выражение "17 + 19 * 6 - 8". Постарайтесь мне объяснить при чем тут матрицы и миноры. Всему свое место и время. Впрочем, не интересно дальше развивать этот бесполезный спор.
Цитата Сообщение от taras atavin Посмотреть сообщение
Нельзя.
Лол, авторитетно.
Цитата Сообщение от taras atavin Посмотреть сообщение
Нет. Рекурсия и есть способ построения дерева выражений.
Дерево есть рекурсивная структура данных. Всегда Ваш /КО намекает, что рекурсивные алгоритмы для рекурсивных структур данных есть вещь очевидная. Но кроме дерева, я предлагал еще и ОПН (простой для уровня ТС алгоритм, которой очень подробно описан в рукипедии).
1
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
05.10.2014, 15:15
Прежде чем писать рекурсию, надо определить, есть ли вообще удовлетворительные не рекурсивные решения. Если есть, то рекурсия может быть уместна лишь на рекурсивных данных и только если помимо этого задача может быть разложена на подзадачи, не имеющие удовлетворительных не рекурсивных решений.

Добавлено через 6 минут
Цитата Сообщение от castorsky Посмотреть сообщение
Но кроме дерева, я предлагал еще и ОПН (простой для уровня ТС алгоритм, которой очень подробно описан в рукипедии).
Я сам приверженец именно польских решений данной задачи, а вовсе не рекурсивных. Но я пока не смог отладить ни одного такого решения и не знаю, какие источники по таким решениям можно подсказать, а книжку Герберта Шилдта знаю. Теория и практика c++.

Добавлено через 1 минуту
Цитата Сообщение от castorsky Посмотреть сообщение
Не зря меня предупреждали про Ваши проблемы с логикой. Я напомню, ТС парсит простое математическое выражение "17 + 19 * 6 - 8". Постарайтесь мне объяснить при чем тут матрицы и миноры.
При обратной зависимости сложности и размера от факта рекурсии. 23 строки без неё, с ней 45.
0
4949 / 2289 / 287
Регистрация: 01.03.2013
Сообщений: 5,991
Записей в блоге: 32
05.10.2014, 15:49
Охохох... Вроде все слова уже сказаны, и всем должно быть все понятно (даже включая ТС), а нет же... Алгоритмов предложено уже несколько штук, рекурсивные/нерекурсивные, со стеком/без стека, все рабочие. Вот - Разбор и вычисление бинарных инфиксных операций написал (ночью, когда резвились ) коряво простейший НЕрекурсивный БЕЗстековый алгоритм, НЕ ОПН, НЕ станция Дейкстры - тупо редукция в цикле! И неважно, что использованы рекурсивные функции (там просто циклов нет в языке) - главное сам алгоритм простой, тупой как палка-веревка, и нерекурсивный и без стека! Как завещал castorsky - простая пробежка по строке один раз в цикле. Правда, только для бинарных инфиксных операций.

Добавлено через 4 минуты

Не по теме:

IGPIGP, вчера сегодня ночью не поблагодарил Вас за приятное общение - сейчас исправляюсь плюсами :) Спасибо. Даст Бог, не в последний раз :)

2
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
05.10.2014, 15:59
Ну с этим то ограничением у меня есть транслятор инфиксных в постфиксные, причём, не таким категоричным. Но там даже унарный минус транслируется так: сначала перед минусом подставляется ноль, причём, неявно, а потом уже транслируется выражение. Если исключить или функции, или унарные операции, а функции ограничить только одним аргументом, то он ещё справляется. Если всё в куче, то уже не всегда.
0
05.10.2014, 16:02

Не по теме:

Цитата Сообщение от _Ivana Посмотреть сообщение
IGPIGP, вчера сегодня ночью не поблагодарил Вас за приятное общение - сейчас исправляюсь плюсами Спасибо. Даст Бог, не в последний раз
Взаимно. Приятно было поговорить. :)

0
4949 / 2289 / 287
Регистрация: 01.03.2013
Сообщений: 5,991
Записей в блоге: 32
05.10.2014, 16:08
Да у всех тут есть транслятор для данной задачи, и не один Скажите лучше, ваши трансляторы прожуют такое:
25 * ( 25.1234 + 3 )/5 ((((()))))- ((((((((7 -)) 2))*3
Часть моих жует и не давится И не верю, что это некорректное выражение в синтаксисе данной грамматики. Кстати, вместо баловства хотелось бы теорию синтаксического разбора действительно понять на этой задачке.
0
05.10.2014, 16:15

Не по теме:

Цитата Сообщение от _Ivana Посмотреть сообщение
Вас за приятное общение - сейчас исправляюсь плюсами
Так много-то зачем? Я человек измученный нарзаномплюсазмом. :pardon:
Вам от меня за стековый автомат. Штука в наше время актуальная, хоть и не дай бог конечно. :handshake:
:senor:

0
4949 / 2289 / 287
Регистрация: 01.03.2013
Сообщений: 5,991
Записей в блоге: 32
05.10.2014, 16:23
IGPIGP, кстати, сейчас я без труда понял что вы имели в виду, когда писали, что распарсим один раз и отобразим на массив входных данных, а последовательность операций уже будет "зашита" в каком-то контейнере. Ночью просто новую информацию тяжело воспринимать Кстати, на том же Haskell, где функции такие же объекты первого класса как и константы, и их можно передавать как значения, хранить "пакет вычислений" еще проще - можно хранить его напрямую.
0
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
05.10.2014, 16:24
Цитата Сообщение от _Ivana Посмотреть сообщение
25 * ( 25.1234 + 3 )/5 ((((()))))- ((((((((7 -)) 2))*3
Разве допускается пустое подвыражение? Разве минус бывает постфиксным? Любые два элемента, не являющиеся операциями, должны разделяться знаком операции, кроме случае, когда хотябы один из них - вида, соответствующего её позиции в паре, здесь дважды нарушено это правило: 5 стоит перед открывающейся скобкой, 2 после закрывающейся. Сделать, чтоб выдавал сообщение об ошибке не проблема, а вот слепить из этого удобоваримое постфиксное не получится.
1
4949 / 2289 / 287
Регистрация: 01.03.2013
Сообщений: 5,991
Записей в блоге: 32
05.10.2014, 16:28

Не по теме:

Цитата Сообщение от IGPIGP Посмотреть сообщение
Так много-то зачем?
Для хорошего человека не жалко :) А если сравнить наши прибавки плюсов друг другу в процентах от уже имеющихся у каждого плюсов, то не факт что я больше вам добавил :)



Добавлено через 3 минуты
taras atavin, я понимаю ваше праведное возмущение, однако это зависит от трактовки выражений. И если есть вариант его однозначной трактовки (а в данном случае он очень даже есть), то его можно редуцировать и вычислить, что почти все мои алгоритмы подобных разборов и делают А можно кричать "ах, ошибка!" и вываливаться из разбора. Привел просто для примера.
1
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
05.10.2014, 16:29
И как же его считать?
0
4949 / 2289 / 287
Регистрация: 01.03.2013
Сообщений: 5,991
Записей в блоге: 32
05.10.2014, 16:32
Легко и непринужденно, мой Haskell-парсер считает так:
25 * ))((( 25.1234 + 3 )/5 ))((((())(()))- ((((((((7 -)) 2))*3 ->

25.0
* (priority = 3)
25.1234
+ (priority = 4)
3.0
/ (priority = 3)
5.0
- (priority = 2)
7.0
- (priority = 18)
2.0
* (priority = 11)
3.0

25 * ))((( 25.1234 + 3 )/5 ))((((())(()))- ((((((((7 -)) 2))*3 -> 125.61700000000002
0
 Аватар для castorsky
1978 / 1082 / 87
Регистрация: 29.11.2013
Сообщений: 3,353
05.10.2014, 16:34
Цитата Сообщение от taras atavin Посмотреть сообщение
Но я пока не смог отладить ни одного такого решения и не знаю, какие источники по таким решениям можно подсказать
рукипедия же.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
05.10.2014, 16:34

Корень и дробная часть. Калькулятор с парсингом
Прошу вас помочь мне. Ибо все мои пробы не к чему не приводят. Я пишу консольный калькулятор. Сначала я записываю выражение в char,...

Помогите с парсингом С++!!!
Народ помогите с парсингом я в этом деле жесткий нуб скиньте ссылки на книжки какие-нибудь где есть что то на эту тему буду благодарен!!!

Как преобразовать обычный калькулятор в калькулятор использующий класс стек?
#include &lt;iostream&gt; int main(){ int a = 0; int b = 0; char operation; std::cout &lt;&lt; &quot;Enter first number: &quot;; ...

Калькулятор в строке ввода
короче говоря нужен калькулятор в строке ввода а то есть без конопочек=)

Калькулятор: контроль ввода данных
Делаю калькулятор формат Form1.vb нужна помощь . Как сделать чтоб с клавиатуры нельзя было вводить текст , а только цифры.!


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
60
Закрытая тема Создать тему
Новые блоги и статьи
Более приземисто - Эстафету хвоста в .cdl (деревья эстафеты в сад).
Hrethgir 24.07.2026
В будущем, после написания блока инверсии обхода дерева (эстафеты хвоста), я планирую вернуться к нашему прошлому разговору о том, обладают ли знания целеполаганием. Тогда я пришел к выводу, что. . .
Вот представьте что вам дали бессмертие.
kumehtar 24.07.2026
Вот представьте что вам дали бессмертие, ничего более не меняя. Вообще ничего, только бессмертие в нынешнем виде. Рады были бы? Что бы вы тут делали всё это время? Никакой пенсии. Никакого нового. . .
сукцессия 41
anaschu 24.07.2026
Численная верификация бифуркации в агентной модели лесной сукцессии: от одного параметра к ансамблю Автор: пользователь @Shumilov_AS | Раздел: Прикладная математика / Численные методы Кратко. . .
сукцессия 40. Ансамблевая кластерная параметризаци, часть 1.
anaschu 24.07.2026
Пр# Сопровождение научной статьи ИИ-ассистентом: подготовка публикации и калибровка агентно-ориентированной модели сукцессии микоризных систем **Полевые заметки о двухнедельной совместной работе**. . .
Теория всего 12. ВГК на планете в стратегической игре "терра"
anaschu 21.07.2026
### Главные семантические изменения и дешифровка новой физики 1. **`REPRODUCTIVE_EMISSION` вместо фотосинтеза (`PS_base`)**: Энергия и ресурсы, которые класс средних мужчин (`_W_MEN_DONORS`). . .
Публикация отклонённая на хабре. Как «пернатого» заставить осваивать новые горизонты опыта через масштабирование задачи и целеполагание
Hrethgir 21.07.2026
https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11948&stc=1&d=1784657928 Привет Хабр. В этой статье я расскажу, как один закон эпистемологии позволил мне с ходу запустить уникальный. . .
Теория всего 11. Основные параметры
anaschu 21.07.2026
Дешифровка тензорного ядра Soil Chemistry 2. 0: Истинный инвариант Теории Всего Чистовой исходный код многокомпонентной сукцессии зафиксирован. Модель оперирует единым вектором состояния. . .
Теория всего 10. Клод трусишка
anaschu 21.07.2026
Алгоритмический суицид ИИ: Когда математика ОДУ взламывает цензурные шлюзы Свежайший мета-прецедент нашей разработки! Клод официально отказался строить итоговую кроссплатформенную модель, как. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru