Консультация № 185528
29.02.2012, 23:46
79.00 руб.
0 19 1
Доброго времени суток!
Дали задание на лабораторную, притом, что на лекциях мы проходим какую-то общую теорию и никакой конкретики.
Из всего написали, как делать ввод и всё.

Собственно, задание:

[QUOTE]
Из входного потока вводится непрямоугольная матрица целых чисел [a[i,j]], i=1, ...,m, j=1, ..., n(i)). Значения m и n(i) заранее не известны и вводятся из входного потока.
Сформировать новую матрицу, поместив в её i-ю строку элементы из i-й строки исходной матрицы, являющиеся палиндромами.
Исходную и полученную матрицы вывести в выходной поток с необходимыми комментариями.
[/QUOTE]

Матрицы вводятся динамически.
Палиндром - выражение, читающееся одинаково с обоих сторон (выражения, типа: "А роза упала на лапу Азора")

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

Код:


#include <iostream>
using namespace std;

//Для задания непрямоугольной матрицы
struct Line{
int n;
double *ar;
Line *matr;
};

//Функция ввода
istream&input(int&a){
while(!(cin>>a)){
if(cin.eof())
break;
cin.clear();
cin.ignore();
}
return cin;
}

//Ввод количества строк
int input(){
int n;
const char*pr="";
do{
cout<<pr<<endl;
pr="error!!!";
cout<<"enter number of int:";
input(n);
}while(n<=0);
return n;
}

//Ввод матрицы
int input(Line*&p){
int m=input();
p=new Line[m];
for(int i=0;i<m;++i){
p[i].n=input();
p[i].ar=new double[p[i].n];
for(int j=0;j<p[i].n,++j)
input(p[i].ar[j]);
}
return m;
}

//Это я начал что-то с выводом предполагать
void output(Line*&p){
for(int i=0;i<m;++i){
for(int j=0;j<p[i].n;++j)
cout<<p[i].n<<endl;
}

int main(){



От Си осталась программа определения палиндрома, выписал из неё функции определения палиндрома, может, как-то поможет (но там ,к тому же использовалась библиотека String.h (Здесь ничего подобного, вроде, не нужно использовать):

Вроде, cin удаляет все пробелы и табуляторы перед словом, поэтому функция проверки на них не нужна.

Код:
 
//Переворот строки
void reverse (char *from, char *to){
int i=strlen(from);
strcpy(to,"");
while(i -->0)
strncat(to,&from[i],1);
}

//Отвечает, палиндром или нет
int isapal(char *str){
char tmp1[80],tmp2[80];
strcpy(tmp1,str);
compress(str,tmp1);
reverse (tmp1,tmp2);
return !strcmp(tmp1,tmp2);
}


Помогите пожалуйста. Желательно с пояснениями, чтобы дальше я хоть мог предположить, как следующие программы делать.

Обсуждение

давно
Профессор
230118
3054
01.03.2012, 12:23
общий
Вы говорите матрица целых чисел, а функция определения палиндрома для строк. Числа в десятичной записи тоже могут быть палиндромами, но тогда их надо переводить в строковый вид. Для хранения матрицы лучше использовать vector. Вектор векторов. Длина вектора в нем есть. А то вы реализуете stl кустарным способом.
Неизвестный
01.03.2012, 16:59
общий
2 Асмик
Да не, нормально, если им так преподавали, то лучше vector-ами не грузить :)

2 Безымянный:

У тебя уже есть решение. Смотри, у тебя первая матрица вводится в цикле, из потока. Надо просто поток убрать и сделать своё добавление элементов. Чисто программерский подход
Осталось разобраться с палиндромами. Последняя функция действительно работает только со строками. Но воспользуемся тем, что у нас числа. Такая строка чисел обладает хорошим свойством: если брать первое и последнее число, вычитать друг из друга, потом результат складывать в отдельную "строчку", потом второе и предпоследнее, и так далее, то в результате для палиндрома мы получим строку с нулями Если делать функцию проверки, то выходит даже проще

Код:
BOOL IsPal(Line &line)
{
int n = line.n;
for(int i=0; i<n; i++)
{
if(line.ar[i] != line.ar[n-i-1])
return FALSE;
}
return TRUE;
}


Всё, в цикле прокручиваем набранную с потока матрицу, подсовывая её строки в эту функцию, если палиндром, то добавляем в новую матрицу.
давно
Старший Модератор
31795
6196
01.03.2012, 17:20
общий
Цитата: 181465
Осталось разобраться с палиндромами. Последняя функция действительно работает только со строками.

Еще раз прочитайте:
Цитата: Асмик Гаряка
Числа в десятичной записи тоже могут быть палиндромами, но тогда их надо переводить в строковый вид

И после этого проверять, к примеру такую строку массива:
21 час 12 минут 21 декабря 2112 года, или 21.12-21.12-2112
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Неизвестный
01.03.2012, 17:25
общий
Вообще-то можно и без строк проверить число на полиндромность. Можно на цифры разбить и в массив положить, например.
давно
Старший Модератор
31795
6196
01.03.2012, 17:36
общий

Цитата: задание
поместив в её i-ю строку элементы из i-й строки исходной матрицы, являющиеся палиндромами.

Не число , строку массива. Это как раз: [21, 12, 21, 12, 2112]
Приблизительно так.
А в строку переводится начиная с последнего элемента, брать постоянно остаток от деления на 10 и добавлять в саму строку. Да, получится реверс цифр элементов одной строки массива, но для палиндрома это без разницы.
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Профессор
230118
3054
01.03.2012, 21:15
общий
Адресаты:
Ни 21, ни 12 не являются палиндромами. Зачем их помещать? Только 2112.
давно
Старший Модератор
31795
6196
01.03.2012, 21:20
общий
Адресаты:
211221122112
А так?
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Старший Модератор
31795
6196
01.03.2012, 21:23
общий
01.03.2012, 21:24
Адресаты:

Перечитал задание: только элементы палиндромы перемещаются в соответствующую строку новой матрицы.
Вы правы.
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Неизвестный
02.03.2012, 06:04
общий
Адресаты:

Я понял так что, палиндром в данном случае: 21 2 21, а не 21 2 12. Что вобщем-то и логичнее, строка состоит из трёх элементов, 21, 2 и 21 а не из пяти 2, 1, 2, 2 и 1.
Так что ничего делить и в строки переводить не надо.
Неизвестный
02.03.2012, 08:10
общий
Спасибо за то, что отвечаете хотя бы...



Цитата: 181465
У тебя уже есть решение. Смотри, у тебя первая матрица вводится в цикле, из потока. Надо просто поток убрать и сделать своё добавление элементов. Чисто программерский подход


Добавление элементов как раз таки из входного потока должно идти. Или Вы про вывод?



Мне посоветовали, кстати, посчитать количество элементов в строке и сравнивать первый с последним, второй с предпоследним и т.д. Только я и тут не понял, как количество элементов строки посчитать, если они из потока вводятся...

Цитата: Асмик Гаряка
Вы говорите матрица целых чисел, а функция определения палиндрома для строк. Числа в десятичной записи тоже могут быть палиндромами, но тогда их надо переводить в строковый вид.

Это не я говорю, я просто с листка с заданием всё перерписал.
Неизвестный
02.03.2012, 08:53
общий
Цитата: 342388
Или Вы про вывод?


Я про заполнение Новой матрицы палиндромами. Но чисто технически, если матрица с палиндромами "не нужна", то можно делать так: берём введённую матрицу и начинаем выводит её же:
если строка палиндром, то выводим в cout, иначе пропускаем.
т.е. что-то типа

Код:
void output(Line*&p){
for(int i=0;i<m;++i){
if(IsPal(p[i])){
for(int j=0;j<p[i].n;++j)
cout<<p[i].n<<endl;
}
else{
continue;
}
}

Кстати, какая версия про палиндромичность правильная? 21 1 12 или 21 1 21? Если вторая, то моя функция подойдёт для определения, т.е. как вот выше в примере уже написал.

Цитата: 342388
Только я и тут не понял, как количество элементов строки посчитать, если они из потока вводятся...


Оно зашито в структуре Line, переменная int n;
В функции ввода матрицы эта переменная заполняется: p[i].n=input();
Неизвестный
02.03.2012, 08:53
общий

Читайте задание внимательно
Сформировать новую матрицу, поместив в её i-ю строку элементы из i-й строки исходной матрицы, являющиеся палиндромами.

Нужно проверять именно элементы, а не строку матрицы.
Неизвестный
02.03.2012, 08:55
общий
PS. Ребята, ну сделайте когда-нибудь обработку кнопки Escape, а то набиваешь-набиваешь сообщение, потом вместо "ё" попал выше и всё...
Неизвестный
02.03.2012, 09:04
общий
Ага, верно... ну пусть сначала сделает простой вариант, потом от простого к правильному
Неизвестный
02.03.2012, 17:55
общий
Цитата: 181465
Кстати, какая версия про палиндромичность правильная? 21 1 12 или 21 1 21? Если вторая, то моя функция подойдёт для определения, т.е. как вот выше в примере уже написал.


Палиндромом будет 21 1 12.


давно
Старший Модератор
31795
6196
02.03.2012, 19:16
общий
03.03.2012, 01:06
Тогда вот код проверки:
Код:
//что где в коде:
const int n=10,m=10,k=100;//размерность
int a[ n ][ m ];//матрица проверямых чисел
int b;//индекс контроля палиндрома, текущее число
int c[ k ];//массив остатков
int d;//индекс контроля палиндрома, счетчик цифр остатка от деления
bool e;//флаг контроля
int i,j;//индексы матрицы
//
//цикл проверки
i=0;//индекс строк матрицы
while( i<n )
{
j=n;//индекс столбцов матрицы
d=0;//счетчик цифр остатка от деления
e=true;//флаг контроля
//
while( j>=0 )
{
b=a[ i ][ --j ];//текущее проверяемое число и следующий столбец
while( b>0 )
{
c[ d++ ]=b % 10;//запоминаем остаток от деления
b/=10;//исключаем остаток
}
}
//
//b=0; // не нужно, т.к. выход из предыдущего цикла по В=0
while( b<d && e )
//
e=c[ b++ ]==c[ --d ]; проверка
//
//Если Е= истина, копируете строку в в другую матрицу, свободные индексы b, d ,j/
i++;//следующая строка матрицы
}
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Неизвестный
03.03.2012, 00:38
общий
Я продлила чуток, оформите ответ тогда, как определитесь с верностью.
давно
Академик
320937
2216
04.03.2012, 13:33
общий
Добрый день! Воможно устроит Вас Code::Blocks .
Код:
#include<iostream>
#include <vector>
#include <iomanip>

using namespace std;
bool is_pali(int n)
{
vector<int> v;
while (n>0)
{
v.push_back(n%10);
n/=10;
}

size_t i=0;
size_t j=v.size()-1;
while (i<j && v[i]==v[j])
{
++i;
--j;
}
return i>=j;
}

int main()
{
size_t m;

cin>>m;
vector <vector <int> >mat1(m);
for (size_t i=0; i!=m; ++i)
{
size_t n;

cin>>n;
for (size_t j=0; j!=n; ++j)
{
int x;
cin >> x;
mat1[i].push_back(x);
}
}

vector <vector <int> >mat2(m);
for (size_t i=0; i!=m; ++i)
{
size_t n = mat1[i].size();
for (size_t j=0; j!=n; ++j)
if (is_pali(mat1[i][j]))
mat2[i].push_back(mat1[i][j]);
}

for (size_t i=0; i!=mat2.size(); ++i)
{
cout << "i=" << i << "=>" ;
for (size_t j=0; j!=mat2[i].size(); ++j)
cout << setw(6) << mat2[i][j];
cout << endl;
}

return 0;
}

Если все нормально - добавлю комментарии и в понедельник оформлю ответ. Сейчас трудно - несколько кнопок на ноутбуке не работают.
давно
Академик
320937
2216
05.03.2012, 15:45
общий
это ответ
Здравствуйте, Безымянный! G++/Code::Blocks.
Код:
#include <iostream>
#include <vector>
#include <iomanip>

using namespace std;
bool is_pali(const int n)
// Является ли число палиндромом?
{
int x=n; // сохраняем передаваемое число во временную переменную
int m=0; // формируем "перевернутое" число
while (x>0) // есть что добавлять?
{
m=m*10+x%10; // по формуле Горнера, но только справа налево
x/=10; // получем остаток после "отсечения" правой цифры
}
return m==n; // "перевенутое" число равно исходному?
}

int main()
{
size_t m;

cin>>m; // количество строк
vector <vector <int> >mat1(m); // матрица
for (size_t i=0; i!=m; ++i)
{
size_t n;

cin>>n; // количество столбцов
for (size_t j=0; j!=n; ++j)
{
int x;
cin >> x;
mat1[i].push_back(x); // увеличиваем размер строки, добавляя элемент
}
}

vector <vector <int> >mat2(m); // результирующая матрица
for (size_t i=0; i!=m; ++i)
{
size_t n = mat1[i].size();
for (size_t j=0; j!=n; ++j)
if (is_pali(mat1[i][j])) // если соответствующий элемент i-й строки 1й матрицы - палиндром
mat2[i].push_back(mat1[i][j]); // добавим его к i- строке 2й мартицы
}

for (size_t i=0; i!=mat2.size(); ++i) // печать 2й матрицы
{
cout << "i=" << i << "=>" ;
for (size_t j=0; j!=mat2[i].size(); ++j)
cout << setw(6) << mat2[i][j];
cout << endl;
}

return 0;
}

Пример. Ввод
Код:
3
4
12 123 121 1221
2
11 11
4
121 121 212 2112

Вывод
Код:
i=0=>   121  1221
i=1=> 11 11
i=2=> 121 121 212 2112

Удачи!
Форма ответа