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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 30.11.2016, 16:46   #1
IgRRR
Новичок
Джуниор
 
Регистрация: 30.11.2016
Сообщений: 6
По умолчанию Мусорное значение в динамическом массиве в структуре

Здравствуйте!

Делаю вычисление факториала от 21 до 30.
Использую длинную арифметику.
Произведение длинного и короткого чисел - написал, работает.
Пытаюсь всё это довести до ума рекурсией, составил алгоритм, вроде всё верно, но на выходе получаю не значение, а мусор.
Не понимаю в чём дело. Много вопросов вставали пока писал программу, но все их смог самостоятельно решить, хоть было и трудно, но здесь понятия не имею как решить. Помогите пожалуйста. Подозреваю, что дело в указателях, но не знаю как исправить. Не могу затягивать, всё перерыл, закончить нужно как можно быстрее, по этому прошу помощи...

Делаю пошагово, поэтому пока отталкиваюсь от значения факториала 20 ({ 0,0,0, 0,4,6, 6,7,1, 8,0,0, 2,0,9, 2,3,4, 2 }), и прописал множитель только для 21 ({ 1,2 }).
Факториал от 0 до 12 - сделал через int, факториал от 13 до 20 сделал через double, думал потом объединить это всё, соответственно от 0 до 20 делать по простому, а дальше уже через произведение длинного и короткого.
Собственно в этом коде как раз от 21 до 30 делаю...

Код:
#include "stdafx.h"
#include <stdio.h>

struct Result {
	int *res;
	int size;
};

struct FResult {
	int *numb1;
	int *numb2;
	int size1;
	int size2;
	int number;
};

Result multiply(int number1[], int number2[], int size_number1, int size_number2)
{
	int length = size_number1 + size_number2 + 1;
	int *subresult = new int[length] {0, }, *result = new int[length] {0, };
	int integer = 0, PlusSubResLen = 0;

	for (int j = 0; j < size_number2; j++)
	{
		for (int i = 0; i < size_number1; i++)
		{




			subresult[i + j] = (number1[i] * number2[j] + integer) % 10;
			//остаток
			integer = (number1[i] * number2[j] + integer) / 10;
			//целое, перенос



		}

		if (integer > 0) //последний знак
		{
        
			subresult[size_number1 + PlusSubResLen] = integer; //конечный символ в результе         <--- сдвиг
			PlusSubResLen++;
			integer = 0;
		}

		for (int i = 0; i <= size_number1 + PlusSubResLen; i++) //сложение массивов
		{
			int temp = (result[i] + subresult[i] + integer) % 10;
			integer = (result[i] + subresult[i] + integer) / 10;
			result[i] = temp;

			subresult[i] = 0;
		}


	}

	int leadnull = -1;
	bool check = false;

	for (int i = 0; i < length; i++) //проверка на лидирующие нули
	{
		if (check == false)
		{
			if (result[i] == 0)
			{
				leadnull = i;
				check = true;
			}
		}
		else
		{
			if (result[i] != 0)
			{
				check = false;
			}
		}

	}

	length = leadnull; //перезадаю длинну, для очевидности

	int *finalresult = new int[length]; //создаю массив нужной длинны


	for (int i = 0; i < length; i++) //записываю данные во временный массив (по сути конечный)
	{
		finalresult[i] = result[i];
	}

	Result final;
	final.res = new int[length];
	final.res = finalresult;
	final.size = length;


	return final;
}

FResult factorial_21To30(FResult old_result)
{
	FResult final;
	if (old_result.number == 20)
	{
		int number1[] = { 0,0,0, 0,4,6, 6,7,1, 8,0,0, 2,0,9, 2,3,4, 2 }; //20!

		int number2[] = { 0,2 }; //20

		final.numb1 = new int[19];
		final.numb1 = number1;

		final.numb2 = new int[2];
		final.numb2 = number2;

		final.size1 = 19;
		final.size2 = 2;
		final.number = 19; //предыдущий типо
	}
	else
	{
	int number2[] = { 1,2 }; //времянка <------------------


	Result subfinal;
	subfinal = multiply(old_result.numb1, number2, old_result.size1, 2);
	// большое число, малое число, размер большого, размер малого

	final.numb1 = new int[subfinal.size];
	final.numb1 = subfinal.res;

	final.numb2 = new int[2];
	final.numb2 = number2; //<---

	final.size1 = subfinal.size;
	final.size2 = 2; //<----
	final.number = old_result.number - 1;

	final = factorial_21To30(final);

	}
	
	return final;
}

int main()
{
	FResult final;

	int number1[] = { 0,0,0, 0,4,6, 6,7,1, 8,0,0, 2,0,9, 2,3,4, 2 }; //20!      число записано наоборот
	int number2[] = { 0,2 }; //20     число записано наоборот

	final.numb1 = new int[19];
	final.numb1 = number1;

	final.numb2 = new int[2];
	final.numb2 = number2;

	final.size1 = 19;
	final.size2 = 2;
	final.number = 21;  // если 20, то факториал 20, если 21, то рекурсия и выводит факториал 21

	final = factorial_21To30(final);

	printf("Novaya stroka:\n");
	for (int i = final.size1 - 1; i >= 0; i--) //вывод результата
	{
		printf("%d", final.numb1[i]);
	}

	


	int number2_2[] = { 1,2 };

	Result finalMult;

	finalMult=multiply(number1, number2_2, final.size1, final.size2);

    printf("\nNovaya stroka:\n");
	for (int i = finalMult.size - 1; i >= 0; i--) //вывод результата
	{
		printf("%d", finalMult.res[i]);
	}

	int s;
	scanf("%d", &s);


	return 0;
}

Последний раз редактировалось IgRRR; 30.11.2016 в 16:55. Причина: добавил данные, исправил ошибки
IgRRR вне форума Ответить с цитированием
Старый 30.11.2016, 16:59   #2
IgRRR
Новичок
Джуниор
 
Регистрация: 30.11.2016
Сообщений: 6
По умолчанию

Результат:
IgRRR вне форума Ответить с цитированием
Старый 30.11.2016, 17:11   #3
IgRRR
Новичок
Джуниор
 
Регистрация: 30.11.2016
Сообщений: 6
По умолчанию

А если немного изменить main (выбрал факториал 20, т.е. должен вывестись факториал 20, без расчётов даже, не входя в рекурсию):

Код:
int main()
{
	FResult final;

	int number1[] = { 0,0,0, 0,4,6, 6,7,1, 8,0,0, 2,0,9, 2,3,4, 2 }; //20!      число записано наоборот
	int number2[] = { 0,2 }; //20     число записано наоборот

	final.numb1 = new int[19];
	final.numb1 = number1;

	final.numb2 = new int[2];
	final.numb2 = number2;

	final.size1 = 19;
	final.size2 = 2;
	final.number = 20;  // если 20, то факториал 20, если 21, то рекурсия и выводит факториал 21
	
	FResult final2;
	final2 = factorial_21To30(final);

	
	printf("Novaya stroka:\n");
	for (int i = final2.size1 - 1; i >= 0; i--) //вывод результата
	{
		final2.numb1[i] = factorial_21To30(final).numb1[i];
		printf("%d", final2.numb1[i]);
	}

	printf("\nNovaya stroka:\n");

	for (int i = final2.size1 - 1; i >= 0; i--) //вывод результата
	{
		printf("%d", final2.numb1[i]);
	}
	

	int s;
	scanf("%d", &s);


	return 0;
}
То получаю такой результат:


Т.е. по сути вывожу два раза один и тот же массив, а получаю разный результат...
IgRRR вне форума Ответить с цитированием
Старый 30.11.2016, 17:14   #4
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,706
По умолчанию

Код:
	final.numb2 = new int[2];
	final.numb2 = number2; //<---
Что вы этим и подобным пытались сотворить? Обычные массивы так не копируются, берите тогда уже stl'ные. Память за вами кто удалять будет?
p51x вне форума Ответить с цитированием
Старый 30.11.2016, 17:25   #5
IgRRR
Новичок
Джуниор
 
Регистрация: 30.11.2016
Сообщений: 6
По умолчанию

Цитата:
Сообщение от p51x Посмотреть сообщение
Код:
	final.numb2 = new int[2];
	final.numb2 = number2; //<---
Что вы этим и подобным пытались сотворить? Обычные массивы так не копируются, берите тогда уже stl'ные. Память за вами кто удалять будет?
Спасибо за ответ!

Пытался скопировать массивы.

Я предполагал, что что-то с памятью.. Но так и не понял как сделать.. и в чём проблема...

Не подскажите как с наименьшим сопротивлением подправить это? Например процитированный вами отрезок, как правильно записать?
IgRRR вне форума Ответить с цитированием
Старый 30.11.2016, 19:48   #6
Hailov
Пользователь
 
Регистрация: 08.10.2016
Сообщений: 18
По умолчанию

final.numb1 = new int[19];
memcpy (final.numb1 , number1, 19*sizeof(int));
Hailov вне форума Ответить с цитированием
Старый 01.12.2016, 10:59   #7
IgRRR
Новичок
Джуниор
 
Регистрация: 30.11.2016
Сообщений: 6
По умолчанию

Цитата:
Сообщение от Hailov Посмотреть сообщение
final.numb1 = new int[19];
memcpy (final.numb1 , number1, 19*sizeof(int));
Спасибо, мне это очень помогло!

Забавно, но ведь я знал этот метод. Хотел его использовать, но т.к. плохо знаком с ним, решил циклом его заменить в одном месте, а в остальных почему-то не догадался и просто присваивал.. В общем использовал это, и решил проблему с мусором. Лишь возвращаемое значение функции не получилось так передать, но там видимо нормально работает указатель. Нашёл ещё некоторые проблему у себя, которые потом решил.

На данным момент программка считает все факториалы от 0 до 29 включительно (у 0 просто ответ 1 задан, а дальше уже рекурсия с произведением длинных на короткие). А вот 30 не правильно считает XD Но тут уже видимо ошибка алгоритмического характера.. Буду искать косяк..
IgRRR вне форума Ответить с цитированием
Старый 01.12.2016, 14:41   #8
IgRRR
Новичок
Джуниор
 
Регистрация: 30.11.2016
Сообщений: 6
По умолчанию

Всем спасибо, задачу решил.
IgRRR вне форума Ответить с цитированием
Ответ


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

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Бинарные сортировки в динамическом массиве hhh_hhh Помощь студентам 2 06.05.2014 08:26
поиск в динамическом массиве novichok-ok C# (си шарп) 2 12.06.2012 23:19
Иерархия в динамическом массиве [BeNdeR] C# (си шарп) 2 12.06.2012 00:44
добавление строк в динамическом массиве Ioane Visual C++ 1 19.02.2012 17:57
Out of memory в динамическом массиве Jor1k Общие вопросы Delphi 16 27.10.2010 18:39