Помощь - Поиск - Пользователи - Календарь
Полная версия: Двумерный массив на С++
Форум «Всё о Паскале» > Современный Паскаль и другие языки > Ада и другие языки
Екатерина
Всем добрый вечер!
Есть задание к лабораторной работе
Написать функцию, для поиска максимального элемента в указанной строке двумерного массива. Сдвинуть в двумерном массиве все строки циклически вправо на количество элементов равное максимальному элементу в этой строке.
Могу я попросить специалистов проверить правильность написания кода?
#include <stdio.h>
#include <tchar.h>
#include <stdlib.h>
#define SIZE_ARRAY 10 //размер массива
#define MAX_INTEGER 10 //максимально допустимое число
int myarray[SIZE_ARRAY][SIZE_ARRAY]; // масив с которым работаем
int _tmain(int argc, _TCHAR* argv[])
{
int NeedString=0; //необходимая строка - строка с которой работаем
int max = 0; //с помощью этой переменной определяем максимальный элемент в строке
printf("Array:\n");

for (int i = 0; i < SIZE_ARRAY; i++) //заполняем массив случайными числами и одновременно выводим его на экран
{
for (int ii = 0; ii < SIZE_ARRAY; ii++)
{
myarray[i][ii] = rand()%MAX_INTEGER;
printf("%3d ", myarray[i][ii]);
};
printf("\n");
}
printf("Vvedi nomer stroki: "); //запрашиваем необходимую строку у пользователя..
scanf("%d", &NeedString);
while (NeedString <= 0 || NeedString > SIZE_ARRAY) //проверяем
{
printf("Vvedi v diapazone ot 1 do %d: ", SIZE_ARRAY);
scanf("%d", &NeedString);
printf("\n");
}
NeedString--;

for (int i = 0; i < SIZE_ARRAY; i++) //ищем максимальное число в строке
{
if (myarray[NeedString][i] > max) max = myarray[NeedString][i];
};
printf("Max integer in string is %d\n", max); //и выводим его на экран
printf("Sdvig %d strok na %d element vpravo\n", NeedString+1, max);
for (int i = 0; i < max; i++) //сдвигаем на нужное число элементов
{
int save = myarray[NeedString][SIZE_ARRAY-1];
printf("%d: ", i+1);
for (int ii = SIZE_ARRAY-1; ii > 0; ii--)
{
myarray[NeedString][ii] = myarray[NeedString][ii-1];
};
myarray[NeedString][0] = save;
for (int i = 0; i < SIZE_ARRAY; i++) printf("%3d ", myarray[NeedString][i]);
printf("\n");
};

scanf("%d", &NeedString);
return 0;
}


Слегка терзают смутные сомнения...
Krjuger
Ну лично у меня был массив 10х10 а потом выводится 7х10,это уже наводит на мысли.... Максимум считает вроде верно,и возник вопрос,как сдвигать циклически только по строке либо циклически по всей матрице(имеется в виду что последний элемент последней строки снате первым элементом первой строки или все таки последней строки).И да сдвиг производится неправильно)))Если рассматривать и первый вариант и второй.

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

#include <stdlib.h>
...
randomize();
int a = random(N); //генерит число в промежутке [0; N)


Если микрософтовский,то

#include <ctime>

using namespace std;
...
srand(time(0));//Надо добивать вот эту строку и библиотеку соответствующую
int a = rand() % N;


Да и еще ваша программа сдвигает не ВСЕ строки,а только те,что находятся ДО введенной пользователем.
Krjuger
В общем когда ответиш на мои вопросы,я постараюсь помоч,если первый вариант верный(слвиг только по строке),то работоспособный вариант у меня уже есть.
Екатерина
Ну я всё-таки склонна думать что сдвигать циклически только по строке. Смысл задания больше похож всё-таки на этот вариант.
А вы метко подметили что числа в массиве каждый раз одинаковые. Я это тоже заметила, но не стала придавать этому большое значение. Массив создался - уже хорошо.
Да, действительно у меня борландовский компилятор
IUnknown
Екатерина, это не С++, это чистый С... На С++ эта задача решается в 5 строк с использованием std::vector как матрицы, + std::rotate для сдвига вектора. Максимум в векторе находится через max_element... Это так, на всякий случай.
Krjuger
Ну собственно я немного переделал ваше.

#include <stdio.h>
#include <tchar.h>
#include <stdlib.h>
#define SIZE_ARRAY 10 //размер массива
#define MAX_INTEGER 10 //максимально допустимое число
int myarray[SIZE_ARRAY][SIZE_ARRAY]; // масив с которым работаем
int _tmain(int argc, _TCHAR* argv[])
{
int NeedString=0; //необходимая строка - строка с которой работаем
int max = 0; //с помощью этой переменной определяем максимальный элемент в строке
printf("Array:\n");

for (int i = 0; i < SIZE_ARRAY; i++) //заполняем массив случайными числами и одновременно выводим его на экран
{
for (int ii = 0; ii < SIZE_ARRAY; ii++)
{
myarray[i][ii] = rand()%MAX_INTEGER;
printf("%3d ", myarray[i][ii]);
};
printf("\n");
}
printf("Vvedi nomer stroki: "); //запрашиваем необходимую строку у пользователя..
scanf("%d", &NeedString);
while (NeedString <= 0 || NeedString > SIZE_ARRAY) //проверяем
{
printf("Vvedi v diapazone ot 1 do %d: ", SIZE_ARRAY);
scanf("%d", &NeedString);
printf("\n");
}
NeedString--;

for (int i = 0; i < SIZE_ARRAY; i++) //ищем максимальное число в строке
{
if (myarray[NeedString][i] > max) max = myarray[NeedString][i];
};
printf("Max integer in string is %d\n", max); //и выводим его на экран
printf("Sdvig %d strok na %d element vpravo\n", NeedString+1, max);
for (int pos=0;pos<max;pos++)
{
for (int i = 0; i < SIZE_ARRAY; i++) //сдвигаем на нужное число элементов
{
int save = myarray[i][SIZE_ARRAY-1];
for (int j=SIZE_ARRAY-1;j > 0 ; j--)
{
myarray[i][j]=myarray[i][j-1];
}
myarray[i][0]=save;
}
}
for (int i = 0; i < SIZE_ARRAY; i++)
{
printf("%d: ", i+1);
for (int j = 0; j < SIZE_ARRAY; j++)
printf("%3d ", myarray[i][j]);
printf("\n");
}
scanf("%d", &NeedString);
return 0;
}


И как подмечено ранее это чистый С,все прелести С++ не используются и я бы еще избавился на вашем месте от #include <tchar.h> ну и сообветственно переделал строку int _tmain(int argc, _TCHAR* argv[]) так как библиотека подключается только ради _TCHAR типа, а argc и argv[] вообще никак в вашей программе не используются и поэтому в их наличии нет необходимости,посоветовать,как переделать не буду,так как не знаю, как в борланде это делается.У меня в визуал студио можно убрать библиотеку и заменить описываемую строку на int main().

Пример имеет более наглядный пример,чем производительный,сдесь последовательно каждый раз во всем матрице происходит сдвиг на 1,конешно же можно избавиться от тройного цикла...Но я решил пока оставить так.

И на будущее обычно координаты у матрици обозначают i,j так еще с математических обозначений повелось и придерживаться таких канонов неплохо было бы)))Это конешно же не обязательно,но так легче разбираться если некоторые стандартизированные вещи есть.
IUnknown
Цитата
Но тут уже зависит от компилятора.Если борландовский,то <...> Если микрософтовский,то <...>
А если использовать "плюсы" - то им по барабану, какой у тебя компилятор, майкрософтовский, борландовский, или от Интела, а может вообще Cameau, или GCC... Используй то, что определено в пространстве имен std, и проблемы разных компиляторов сразу куда-то улетучиваются.

В общем, если интересно, как это может выглядеть - вот так:
#include <vector>
#include <iterator>
#include <algorithm>
#include <cstdlib>
#include <ctime>
#include <iostream>

int my_rand()
{
return std::rand() % 10;
}

int main()
{
size_t size = 10;
std::vector< std::vector<int> > mx(size, std::vector<int>(size, 0));
std::srand(std::time(0));
for(size_t i = 0; i < size; i++)
{
// Заполняем строки случайными значениями
std::generate(mx[i].begin(), mx[i].end(), my_rand);
// Покажем, что получилось
copy(mx[i].begin(), mx[i].end(), std::ostream_iterator<int>(std::cout, " "));
// Заодно сразу здесь выведем максимальный элемент
std::cout << " , max = " << *max_element(mx[i].begin(), mx[i].end()) << std::endl;
// И сдвинем циклически вправо на значение макс. элемента
std::rotate(mx[i].begin(), mx[i].end() - *max_element(mx[i].begin(), mx[i].end()),
mx[i].end());
}
std::cout << std::endl;

// Ну, и, разумеется, покажем, что получилось в результате:
for(size_t i = 0; i < 10; i++)
{
copy(mx[i].begin(), mx[i].end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
}
std::cin.get();
return 0;
}
Екатерина
СПАСИБО!!! Программа вроде работает как надо. Правда у меня по моему "куку поехала" - мне почему-то кажется что сдвиг получается не вправо, а влево. Добавила randomize(); матрица при каждом запуске стала меняться!

int NeedString=0; //необходимая строка - строка с которой работаем
int max = 0; //с помощью этой переменной определяем максимальный элемент в строке
printf("Array:\n");
randomize();
for (int i = 0; i < SIZE_ARRAY; i++) //заполняем массив случайными числами и одновременно выводим его на экран
{
for (int ii = 0; ii < SIZE_ARRAY; ii++)


От библиотеки #include <tchar.h> не смогла избавиться.
Котику IUnknown должна сказать что вектора мы, к сожалению, ещё не проходили, поэтому пока для меня дремучий лес.
Очень благодарна вам за профессиональные подсказки.
Krjuger
А вы их и не пройдете,принципы работы с вектором такие же как и с обычным одномерным массивом,просто некоторые действия уже реализованы в библиотеке,а точнее все основные действия,которые чаще всего используются.Никто не будет вас обучать каждой библиотеке и работе с ней.Так что все это уже идет на уровне самообучения.
Замените

int _tmain(int argc, _TCHAR* argv[])


на

int main()


И удали соответствующую библиотеку.
IUnknown
Просто заменить _tmain на main может быть недостаточно. Все зависит от настроек проекта. Если проект НЕюникодный (т.е., Project->Options->_TCHAR maps to установлено в char), то все будет нормально после такой замены. Если же там выбрано wchar_t, то линкер будет против...
Екатерина
Ой... не то сморозила.
Екатерина
Всё замечательно работает! Спасибо! Замена
int _tmain(int argc, _TCHAR* argv[])
на просто int main() оправдала себя на все 100. А проект создавался обычным образом: File-> New -> Other -> Console Application -> C++ -> OK
Krjuger
Да не, все его создают обычным образом просто настройки могут быть разные изначально и от этого может зависеть то,что написал IUnknown ранее.
IUnknown
Чем быстрее ты научишься ЧИТАТЬ, а не просматривать ответы, тем проще тебе будет... Я что, где-то говорил о том, что важно как проект был СОЗДАН? Покажи, где именно. Я сказал, что важно, является ли проект юникодным. При создании ты указываешь тип проекта - консольное приложения. Что там у тебя выбрано в настройках Билдера, какой проект по умолчанию будет создаваться, Unicode или ANSI - это мне неизвестно. Но если ты считаешь, что ВСЕГДА будет столь же просто избавиться от _tmain, то тебя ждут разочарования. Это далеко не всегда так.

Хотя... Можешь продолжать в том же духе, не читая того, что пишут, а только бегло просматривая... Зачем тебе, в конце концов, понимать, откуда вдруг возьмется проблема, о которой я написал? Тебе ж это не нужно, у тебя ж один раз все отработало, да?
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.