Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 08.06.2010, 21:13   #1
TripleX
Пользователь
 
Регистрация: 30.03.2009
Сообщений: 16
По умолчанию Pelles C: операции над двоичными числами в файле, удаление строки из массива

Запарился уже с двумя задачами. Прошу помочь с решением
1) Дана квадратная целочисленная матрица размера N×N. Удалить из матрицы строку, содержащую максимальную разницу между элементами главной и побочной диагоналей. Полученную матрицу вывести на экран.
Все сделал, проблема только с удалением. Пробовал просто не выводить ее в конце - препод сделал замечание. А как делается удаление "затиранием" строки я чет не пойму/не могу реализовать. Просьба если что, объяснить на моей программе. Вот код:
Код:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

int main(int argc, char *argv[])
{
	//Описание переменных
    int N,i,j,different=0,strNum=0;
	//Приглашение к вводу размера массива
    printf("Enter dimension:\n");
	//Ввод размера массива
    scanf("%d",&N);
    //выделение памяти под динамический массив
    int **arr=(int**) malloc(sizeof(int*) * N);
    for (i=0;i<N;i++)
    	arr[i]=(int*) malloc(sizeof(int) * N);
    //заполнение массива
    for (i=0;i<N;i++)
    	for (j=0;j<N;j++)   
    	 {
     	    printf("Enter value [%d][%d]:\n",i,j);
      	   scanf("%d",&arr[i][j]);
     	}
    printf("Source array: \n");
    //вывод исходного массива и алгоритм выбора строки с максимальной по модулю
    //разницей между элементами главной и побочной диагонали
    for (i=0;i<N;i++)
    {
    	if(abs(arr[i][i]-arr[i][N-i-1])>different)
       	{
        	different=abs(arr[i][i]-arr[i][N-i-1]);
        	strNum=i;                                                 
       }
      for (j=0;j<N;j++)   
      	   printf("%7d",arr[i][j]);
     printf("\n");
     }
 	//Удаляем строку, затирая старую (здесь проблема)   
	for (int i=strNum;i<N-1;++i) arr[i]=arr[i+1];
	//Вывод результата
     printf("Result: \n");
     for (i=0;i<N;i++)
   	  {
     	 for (j=0;j<N;j++)
  		       	  printf("%7d",arr[i][j]);
 			  printf("\n");
  	   }
	//Приостановка выполнения программы
	getchar();
    return EXIT_SUCCESS;
}
2) Бинарный файл содержит вещественные числа. Увеличить в два раза все значения меньшие среднего арифметического значения всего файла.
Заменил printf/scanf на fwrite/fread и программа начала зацикливаться.
Вот код:
Код:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
int main(int argc, char *argv[])
{
	//Описание переменных
	char fname[16];
	int n=0,i=0;
	double avg=0,num=0;
	FILE *input,*output;
	//Запрашиваем имя файла и создаем его
	printf("Enter filename:\n");
	gets(fname);
	input=fopen(fname,"wb+");
	//Запрашиваем количество вводимых чисел
	printf("How much numbers?\n");
	scanf("%d",&n);
	//Запрашиваем числа для ввода и пишем в файл
	for (i=0;i<n;i++)
		{
			printf("Number %d:\n",i+1);
			scanf("%lf",&num);
			//fwrite(input,"%lf ",num);
			fwrite(&num, sizeof(double),1, input);
		}
	fclose(input);
	//Открываем файл для чтения
	input=fopen(fname,"rb");
	n=0; num=0;
	//Считываем числа и считаем среднее
	printf("Source file content:\n");
	while(!feof(input))
		{
			//fscanf(input,"%lf ",&num);
		fread(&num, sizeof(double), 1, input);	
		printf("%lf ",num);
			avg+=num;
			n++;
		}
	avg/=n;
	printf("\nAverage: %lf\n",avg);
	//Ставим курсор снова в начало файла
	rewind(input);
	//присоединение строки
	output=fopen("tmp.tmp","wb+");
	//Считываем числа из файла и сравниваем их с средним значением
	//Записываем результаты во временный файл
	while(!feof(input))
		{
			//fscanf(input,"%lf ",&num);
			fread(&num, sizeof(double), 1, input);
			if (num<avg) num*=2;
			//fprintf(output,"%lf ",num);
			fwrite(&num, sizeof(double), 1, output);
		}
	fclose(input);
	fclose(output);
	//удалить input,переименовать output
	remove(fname);
	rename("tmp.tmp",fname);
	input=fopen(fname,"rb");
	//Считать данные из полученного файла и вывести на экран
	printf("Result file content:\n");
	while(!feof(input))
		{
			fscanf(input,"%lf ",&num);
			printf("%lf ",num);
		}
	fclose(input);

getchar();
return EXIT_SUCCESS;
}

Последний раз редактировалось TripleX; 08.06.2010 в 23:12.
TripleX вне форума Ответить с цитированием
Старый 09.06.2010, 09:10   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Насчет первого, удаление:
Код:
	arr[strNum]=0;
	for(i=0;i<N;i++){
 		for(j=0;j<N;j++){
			if(arr[i]) {
				printf("%7d\t",arr[i][j]);
			}
 		} printf("\n");
	}
Так подойдет?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 09.06.2010, 10:57   #3
TripleX
Пользователь
 
Регистрация: 30.03.2009
Сообщений: 16
По умолчанию

В принципе да. Спасибо! Если не сложно, объясни, пожалуйста, как он работает. Строка обнуляется, а что дальше? Что за условие:
Код:
if(arr[i]) {
	printf("%7d\t",arr[i][j]);
	}
TripleX вне форума Ответить с цитированием
Старый 09.06.2010, 11:10   #4
Snejnaya
Форумчанин
 
Регистрация: 12.05.2010
Сообщений: 219
По умолчанию

Код:
if(arr[i])
условие ложно, если arr[i] равно 0 и истинно в другом случае

Цитата:
Пробовал просто не выводить ее в конце - препод сделал замечание.
У меня складывается впечатление, что препод хотел, чтобы ты изменил саму матрицу, а не просто вывод на экран. Т.е. если вторую строку удалил, то третью двигаешь на ее место, четвертую на место третьей и т.д. до конца. Разве не так?
Snejnaya вне форума Ответить с цитированием
Старый 09.06.2010, 11:23   #5
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
пожалуйста, как он работает
Дело в том что тут небольшой финт. Факически тут очищается указатель на некую строку матрицы. Это можно считать удалением, но преподы оч. любят придираться, так что ты уж постарайся ответь на вопрос пани Снежной, мало ли каким методом нужно удалять строку, может быть действительно с полной перестановкой типа Shrink
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 09.06.2010, 11:58   #6
Snejnaya
Форумчанин
 
Регистрация: 12.05.2010
Сообщений: 219
По умолчанию

Stilet

Меня просто "зацепила" фраза
Цитата:
Полученную матрицу вывести на экран.(полученную после удаления строки)
Почти на 100% уверена, что препод скажет, мол - надо матрицу целиком на экран выводить, а ты не все строки выводишь - гуляй, Вася!
Snejnaya вне форума Ответить с цитированием
Старый 09.06.2010, 12:11   #7
TripleX
Пользователь
 
Регистрация: 30.03.2009
Сообщений: 16
По умолчанию

Цитата:
Сообщение от Snejnaya Посмотреть сообщение
У меня складывается впечатление, что препод хотел, чтобы ты изменил саму матрицу, а не просто вывод на экран. Т.е. если вторую строку удалил, то третью двигаешь на ее место, четвертую на место третьей и т.д. до конца. Разве не так?
Скорее всего. Так как я делал - неправильно?
Код:
for (int i=strNum;i<N-1;++i) arr[i]=arr[i+1];
Цитата:
Сообщение от Stilet Посмотреть сообщение
Дело в том что тут небольшой финт. Факически тут очищается указатель на некую строку матрицы. Это можно считать удалением, но преподы оч. любят придираться, так что ты уж постарайся ответь на вопрос пани Снежной, мало ли каким методом нужно удалять строку, может быть действительно с полной перестановкой типа Shrink
Хотелось бы чтоб наверняка. Доработка у нас платная. А так идея мне нравится)
А что за перестановка типа shrink? Гугль какой-то мусор выдает на это. Да и на форуме ничего нет.

Последний раз редактировалось TripleX; 09.06.2010 в 12:20.
TripleX вне форума Ответить с цитированием
Старый 09.06.2010, 12:53   #8
Snejnaya
Форумчанин
 
Регистрация: 12.05.2010
Сообщений: 219
По умолчанию

Код:
for (int i=strNum;i<N-1;++i) arr[i]=arr[i+1];
я бы сделала
Код:
for (i=strNum; i<N-1;i++) arr[i]=arr[i+1];
Если я не ошибаюсь, когда ты пишешь ++i, сначала значение i увеличивается на 1, а потом обрабатывается и тогда у тебя идет обращение к элементу массива arr[N], который не существует.
Snejnaya вне форума Ответить с цитированием
Старый 09.06.2010, 13:24   #9
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
Хотелось бы чтоб наверняка.
Не завидую... Такая перестановка работа для людей с крепкими нервами, особенно если это классический Си...
Тут же наверное препод потребует очистить память после сжатия...
Я не настолько силен в Си чтоб такую дурную работу с ходунаписать.
Цитата:
А что за перестановка типа shrink?
Та это есть такое понятие как упаковывание базы данных. как раз предполагает физическую переписку записей (строк) на место удаленных, за счет чего база сжимается.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 09.06.2010, 20:00   #10
TripleX
Пользователь
 
Регистрация: 30.03.2009
Сообщений: 16
По умолчанию

Цитата:
Сообщение от Snejnaya Посмотреть сообщение
Если я не ошибаюсь, когда ты пишешь ++i, сначала значение i увеличивается на 1, а потом обрабатывается и тогда у тебя идет обращение к элементу массива arr[N], который не существует.
А что в таком случае делать с последней строкой? Строки сдвигаются, а последнюю придется либо снова пропускать при выводе, либо вводить вторую переменную (для обозначения строки) и ее уменьшать. Все равно придерется)

Последний раз редактировалось TripleX; 09.06.2010 в 23:13.
TripleX вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
цикл for с двоичными числами samouelson Общие вопросы Delphi 4 11.03.2010 23:18
Работа с двоичными числами в Delphi Moneo Помощь студентам 17 22.01.2010 15:10
TurboPascal: логические операции над целыми числами плюс перевод.... ulala Помощь студентам 4 21.10.2009 12:00
Нужна помощь с двоичными числами Rusa85 Помощь студентам 3 03.02.2009 09:01