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

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

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 03.02.2012, 00:10   #1
Mr.BL@CK
Пользователь
 
Регистрация: 17.11.2010
Сообщений: 27
По умолчанию Матрица.Замена нулевых элементов на среднее арифметическое

Доброй ночи,форумчане.Прошу помощи с вот таким заданием :

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

Сделать ввод с клавиатуры/ из файла и вывод данных на экран / в файл

Второе проблем не представляет (как ни странно)

А вот по поводу матрицы - сам алгоритм понимаю,как сделать,а вот написать проблема...

Если нулевой элемент - тогда искать среднее арифметическое в строке
А потом - поменять.Но ,я на С пока новичек..нормально написать не могу(
Mr.BL@CK вне форума Ответить с цитированием
Старый 03.02.2012, 00:17   #2
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Цитата:
нормально написать не могу
Дык попробуй хоть как-нибудь написать, не бойся
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.

Последний раз редактировалось Alex11223; 03.02.2012 в 00:19.
Alex11223 вне форума Ответить с цитированием
Старый 03.02.2012, 02:28   #3
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от Mr.BL@CK Посмотреть сообщение
я на С пока новичек..нормально написать не могу
Пиши не_нормально.
_Bers вне форума Ответить с цитированием
Старый 03.02.2012, 15:17   #4
Сыроежка
Форумчанин
 
Регистрация: 01.07.2011
Сообщений: 423
По умолчанию

Цитата:
Сообщение от _Bers Посмотреть сообщение
Пиши не_нормально.
Предлагаете писать ненормально? Без проблем! Как раз это у меня лично хорошо получается!

Код:
#include	<iostream>
#include	<iterator>
#include	<algorithm>
#include	<numeric>
#include	<functional>

template <typename Container>
struct replace_zero: std::unary_function<Container, void>
{
	void operator ()( Container &c ) const
	{
		std::replace( std::begin( c ), std::end( c ), 0,
			 std::accumulate( std::begin( c ), std::end( c ), 0 ) /
			 std::count_if( std::begin( c ), std::end( c ),
			 std::bind2nd( std::not_equal_to<int>(), 0 ) ) );
	}
};

int main()
{

	int a[][14] = { { 1, 0, 3, 4, 0, 0, 7, 3, 0, 9, 5, 0, 0, 0 },
	                       { 7, 5, 0, 0, 0, 11, 1, 3, 0, 2, 0, 0, 1, 9 } };

	for ( auto it = std::begin( a ); it != std::end( a ); ++it )
	{
		std::copy ( std::begin( *it ), std::end( *it ),
			  std::ostream_iterator<int>( std::cout, " " ) );
			  std::cout << std::endl;
	}
	std::cout << std::endl;
		
	std::for_each( std::begin( a ), std::end( a ), replace_zero<int[14]>() );

	for ( auto it = std::begin( a ); it != std::end( a ); ++it )
	{
		std::copy ( std::begin( *it ), std::end( *it ),
			  std::ostream_iterator<int>( std::cout, " " ) );
			  std::cout << std::endl;
	}
		
	std::cout << std::endl;

	return ( 0 );
}
Только я в своем коде не проверяю, что вся строка может состоять из нулей, поэтому может быть ошибка деления на 0. Но это лекго поправить, если сначала подсчитать число ненулевых элементов.

Код:
template <typename Container>
struct replace_zero: std::unary_function<Container, void>
{
	void operator ()( Container &c ) const
	{
		int n = std::count_if( std::begin( c ), std::end( c ),
			    std::bind2nd( std::not_equal_to<int>(), 0 ) );

		if ( n )
		{
			std::replace( std::begin( c ), std::end( c ), 0,
			          std::accumulate( std::begin( c ), std::end( c ), 0 ) / n );
		}
	}
};
Тут даже еще более ненормально можно написать, заменив предложение

Код:
std::for_each( std::begin( a ), std::end( a ), replace_zero<int[14]>() );
на

Код:
std::for_each( std::begin( a ), std::end( a ), replace_zero<decltype( a[0] )>() );
Со мной можно встретиться на www.clipper.borda.ru

Последний раз редактировалось Stilet; 05.02.2012 в 15:52.
Сыроежка вне форума Ответить с цитированием
Старый 03.02.2012, 18:31   #5
Mr.BL@CK
Пользователь
 
Регистрация: 17.11.2010
Сообщений: 27
По умолчанию

О__о и в самом деле интересно
Но мне бы на С...а не на С++..А судя из строки #include <iostream> = тут именно на них
Mr.BL@CK вне форума Ответить с цитированием
Старый 03.02.2012, 18:58   #6
Сыроежка
Форумчанин
 
Регистрация: 01.07.2011
Сообщений: 423
По умолчанию

Цитата:
Сообщение от Mr.BL@CK Посмотреть сообщение
О__о и в самом деле интересно
Но мне бы на С...а не на С++..А судя из строки #include <iostream> = тут именно на них
Глянь сюда http://clipper.borda.ru/?1-6-0-00000...0-0-1328273726. Может быть на основе этого сам сможешь написать?
Со мной можно встретиться на www.clipper.borda.ru
Сыроежка вне форума Ответить с цитированием
Старый 05.02.2012, 14:29   #7
Mr.BL@CK
Пользователь
 
Регистрация: 17.11.2010
Сообщений: 27
По умолчанию

Код:
 
#include<stdio.h>  
#include<alloc.h> 
#include<process.h>
#include<conio.h> 
/*************************************************************************/
 
FILE *fout;

/*************************************************************************/
 
 FILE *zapros_out();
 void inputmatr(float x[][20],int *m,int *n,char c);
 void outputmatr(float x[][20],int m,int n,char *msg);
 float sr_znach(float (*x), int n);
 float zamena(float (*x),int n,int m);
/*************************************************************************/
 

 void main()
  {


 
   float x[20][20], (*y)[20], CP;


      int  mx,nx,my,ny,i,j,kol,Sr;

 

   y = (float (*)[20])malloc(20*20*sizeof(float));
   remove("rez.dat");/*удаление файла результатов, если он имеется в текущем
   директории*/
   clrscr();

 
   fout=zapros_out();

 
   clrscr();
   inputmatr(x,&mx,&nx,'x');
   outputmatr(x,mx,nx,"Исходная матрица x");
    sr_znach(x,nx);
  zamena(x,mx,nx); 
   outputmatr(x,mx,nx,"Обработанная матрица x");
   printf(" Для продолжения нажмите любую клавишу\n");
   getch();

 

   CP=x[0][0];
   printf("/n/t/tCP=[%f]",CP);
 


 
   clrscr();
   inputmatr(y,&my,&ny,'y');
   outputmatr(y,my,ny,"Исходная матрица y");
    sr_znach(y,ny);
   zamena(y,my,ny); 
   outputmatr(y,my,ny,"Обработанная матрица y");

   printf(" Для выхода в DOS нажмите любую клавишу\n");
   getch();
   free(y);
   if(fout!=stdout)fclose(fout);
  }
/***************************************************************/
 FILE  *zapros_out()
 {int p; FILE *f;
   printf("\n Результаты выполненеия программы выводить на экран<s>\n\
                 или в файл результатов на диске <f>?\n\n");
   if(((p=getch())=='f')||(p=='F')||(p=='а')||(p=='А'))
    {
     if((f=fopen("rez.dat","at"))==NULL)/*Открытие файла в текстовом режиме
       для записи в конец файла*/
      {
       printf("Невозможно открыть файл для результатов\n"
           " Для выхода в DOS нажмите любую клавишу\n");
       getch();
       exit(0);
      }
    }
     else f=stdout;
  return f;
 }



 

float sr_znach(float (*x), int n)
{float Sr=0;
int i,kol=0;
for(i=0;i<n;i++)
	if(x[i]!=0)
		Sr+=x[i];
	else kol++;
	Sr/=(n-kol);
return Sr;
}


 

 float zamena(float (*x),int n,int m)
{
int i,j;
for(i=0;i<n;i++)
	for(j=0;j<m;j++)
		if(*(x+i*n+j)==0)
			*(x+i*n+j)=sr_znach((x+i*n),m);
			
}

 

 


/***************************************************************************/
 

 void outputmatr(float x[][20],int m,int n,char *msg)
  {int i,j;;
   fprintf(fout,"\t%s\n",msg);
   for(i=0;i<m;i++)
    {
     for(j=0;j<n;j++)
      fprintf(fout,"%8.2f",x[i][j]);
     fprintf(fout,"\n");
    }
  }

 
 

 void inputmatr(float x[][20],int *m,int *n,char c)
  {
   float xr;
   int  i,j,pr;
   FILE *f; char p;
   //clrscr();
   printf("Ввод размеров и элементов матрицы %c\n",c);
   printf("\n\n      Введите размеры матрицы m,n<=20\n ");
   scanf("%d%d",m,n);
   printf(" Ввод матрицы с клавиатуры<k> или из файла<f>?\n");
   if(((p=getch())=='f')||(p=='F')||(p=='а')||(p=='А'))
    {
     p='f';
     if((f=fopen("matr.dat","rt"))==NULL)
      {
       printf("Исходный файл не найден\n Для выхода в DOS нажмите "
               "любую клавишу");
       getch();
       exit(0);
      }
    }
     else f=stdin;
   if(p!='f')printf("Введите элементы матрицы\n");
   for(i=0;i<*m;i++)
    for(j=0;j<*n;j++)
     {
      pr=fscanf(f,"%f",&xr);
      if(pr<=0)
       {
        if(pr==EOF)
         printf("Обнаружен конец файла\n");
        else
         printf("Ошибка чтения %s \n",(p=='f')?"из файла":"с клавиатуры");
        printf("Для выхода в DOS нажмите любую клавишу");
        getch();
        exit(0);
       }
      else x[i][j]=xr;
     }
   if(p=='f')fclose(f);
  }
Сделал что то подобное.
Однако,при вызове процедуры zamena - вылет
Видимо,что то как то не так передал.Не подскажете,в чем может быть дело?
Mr.BL@CK вне форума Ответить с цитированием
Старый 05.02.2012, 15:15   #8
Сыроежка
Форумчанин
 
Регистрация: 01.07.2011
Сообщений: 423
По умолчанию

Я не смотрел всю вашу программу, но очевидно, что у вас неправльно объявлены параметры функции zamena с учетом того, какие аргументы вы ей передаете. Вы передаете в эту функцию массив x , который у вас объявлен как float x[20][20]


Вот ваш вызов функции:

zamena(x,mx,nx);

Но при передаче имени массива в качестве аргумента функции он преобразуется в указатель на свой первый элемент. Так как это двумерный массив, то его первым элементом будет одномерный массив, соответстввующий первой (нулевой) строке массива. Кроме того так как из функции вы ничего не возврращаете, она должна иметь тип возвращаемого значения void. Поэтому функция должна быть объявлена либо как

void zamena( float x[][20], int n, int m );

либо как

void zamena( float ( *x )[20], int n, int m );

Есть третий вариант. Вы оставляете объявление параметров функции так, как оно у вас есть (только скобки вокруг x не нужны, а также типа возвращаемого значения должен быть void)

void zamena( float *x, int n, int m )

но при вызове функции в качестве аргумента указываете не имя массива, а адрес его первого элемента

zamena( &x[0][0],mx,nx);

Тогда вам не придется переписывать тело этой функции.
Если же вы сделаете так. как я указал в первых двух вариантах, то тогда тело функции будет выглядеть следующим образом


Код:
void zamena( float ( *x )[20], int n, int m )
{
   int i, j;
   
   for( i = 0; i<n; i++ )
   {
      for( j = 0; j<m; j++ )
      {
         if ( x[i][j] ==0 ) x[i][j] = sr_znach ( x[i], m );
      }
   }			
}
И лучше среднее значение ненулевых элементов вычислять не каждый раз для нулевого элемента строки в теле цикла, а один раз его вычислить до цикла, так как это является константной величиной для каждой строки
Со мной можно встретиться на www.clipper.borda.ru

Последний раз редактировалось Сыроежка; 05.02.2012 в 15:31.
Сыроежка вне форума Ответить с цитированием
Старый 05.02.2012, 18:08   #9
Mr.BL@CK
Пользователь
 
Регистрация: 17.11.2010
Сообщений: 27
По умолчанию

Спасибо большое за помощь!
Вначале попробовал
Код:
void zamena( float *x, int n, int m )

но при вызове функции в качестве аргумента указываете не имя массива, а адрес его первого элемента

zamena( &x[0][0],mx,nx);
но с удивлением обнаружил,что моя процедура замены заменяет только один ненулевой элемент
Если их в строке 2 и более - она остальные оставляет 0.
Попробовал то,что вы предложили - заработало нормально
Mr.BL@CK вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Дана матрица найти среднее арифметическое ее элементов! На C#! Александр10 C# (си шарп) 2 27.05.2011 15:03
среднее арифметическое значение элементов матрицы mxm. вектор из минимальных элементов (Бейсик) Люстик Помощь студентам 1 17.03.2011 08:20
Делфи.среднее геометрическое элементов массива.среднее арифметическое каждой строки матрицы Karrina Помощь студентам 0 06.12.2010 18:32
найти среднее арифметическое элементов массива состоящее из 5 элементов viatlon Общие вопросы C/C++ 9 12.12.2009 00:45
Дана квадратная матрица порядка N. Вычислить среднее арифметическое положительных элементов матрицы, Grisha248 Помощь студентам 2 22.05.2009 17:37