Loading...
dstefanova avatar dstefanova 67 Точки

[Homework] C# Basics - Introduction to programming - Problem{3} - Some Factorials - possible options

Здравейте. Търсих подобна тема, но не успях да я намеря. Ако се повтарям моля да бъда извинена.

Работя върху идея за решение на тази задача, но имам нужда от помощ, за да я разработя. 

Според мен идеята на задачата не е да влезем в Гугъл и да напишем 100!, а да намерим оптимален алгоритъм за решаването й на база наученото до момента. 

Вариант1: Имайки предвид, че написани в двуичен вид, числата ще придобият вид на нули и единици, то следователно ще умножаваме 100 числа само по 0 и само по 1. Тоест умножението ще се сведе до минумум, после ще обърнем обратно в десетичен вид и воала. 

Вариант2: Да представим множителите като прости числа на степен, умножени по 2 на някаква степен. Идеята е, че всички числа, които не са сложни, или са кратни на 2, или на други прости числа. Така като гледам ще получим 50 прости числа на степени. 

Не съм сигурна доколко тези два варианта звучат рационално, но ще съм ужасно благодарна, ако някой ми даде малко насоки как да ги доосъвършенствам :)

Благодаря предварително, 

Деница

Тагове:
0
Programming Basics
JOHNY avatar JOHNY 196 Точки

Привет!

Всъщност в това домашно наистина се иска основно работа с Google или друга търсачка. Идеята му е да научи бъдещите студенти да търсят бързо и рационално нужната им информация.

Код не е нужно да пишеш, но ще кажа няколко думи за двата ти варианта.

Вариант 1 - Мисля, че се заблуждаваш за "по-малкото умножение, защото ще умножаваме само по 0 и 1". Всъщност умножението е абсолютно същото, а само числата ще бъдат представени в двоичен код. Това не означава, че 17 е 0 или 1, а вероятно е 10001 (смятам на ум). Като добавиш към това, че машината така или иначе "вижда и брои" в двоичен код, то пресмятането така или иначе ще бъде по този начин, но потребителят няма да види самите процеси, а само крайният резултат, при това в десетичен формат.

Вариант 2 - Излишно усложнение е това. От умножение да преминаваш в повдигане на степен, което също е вид умножение? Какво печелиш?

Ако говорим за алгоритъм помисли над следния:

1. Въвеждаме число n  (в твоя случай е 100)

2. Въвеждаме междинно число temp да речем равно на 1

3. Започваме цикъл от 1 до n, като при всяко преминаване през цикъла  умножаваме temp по числото от цикъла. Например по 1, по 2 ч, по 3... по n.

4. Цикъла приключва и temp всъщност е равно на n!

Като код е буквално 5-6 реда и ще работи чудесно с подходящите променливи (BigInteger да речем).

Ако имаш и друга идея за алгоритъм - нека я обсъдим. Жокер: описаният по-горе може да бъде съкратен/оптимизиран. Как?

Поздрави!

2
15/05/2015 08:57:10
dstefanova avatar dstefanova 67 Точки

Здравей, Джони, благодаря ти за отговора. 

Говорейки за алгоритъм на машина, аз бих избрала следния:

1. Задавам N=1; i=1;

2. N=N*i; i=i+1

3.Вкарвам цикъл: 

Is N> 100?

if yes : извеждам N

if not: се връщам обратно на 2. :)

Благодаря ти пак, че ми обясни защо не биха ми работили вариантите. Аз им се радвах като на писани яйца, 3 дни ги мисля, ама като не става - не става! :)

Поздрави, 

Деница

1
JOHNY avatar JOHNY 196 Точки

Здрасти Деница,

Всъщност труда ти не е напразен и никъде не казвам, че няма да работят. Напротив - във вариант 1 описваш как работи... самата машина.:)

По-хубавото е, че си проявила творчество и логическа мисъл за да намериш вярното решение. 

Ще се опитам да го доразвия и да ти помогна с някои оператори, които ще учиш по време на курса.

"1. Задавам N=1; i=1;"

Тук по-скоро ще оставим потребителят да въведе N за да може да пресмятаме всеки път различни стойности (наример 100!, 214!,7! и т.н.). Тоест N=? (въведено от потребителя число, а i за момента ще го наречем temp от temporary - временен резултат).

Ето като код: 

int temp = 1;

int n = int.Parse(Console.ReadLine());

Преведен кодът означава "Променливата temp е със стойност 1. Вземи числото, което въвежда потребителя и присъедини неговата стойност на n".Тук няма да се впускаме все още в това доколко ще ни ограничи използването на int, а само ще подскажем, че има такова ограничение. Иначе казано ако искаш да пресметнеш 16534! това няма да е възможно. Като допълнение по-нататък ще разгледаме и възможността потребителят умишлено да ни лъже и да не въвежда стойност, а символ (буква да речем). В момента няма да се занимаваме с това.

 

"2. N=N*i; i=i+1

3.Вкарвам цикъл: 

Is N> 100?"

 Това можеш да го направиш по няколко начина.

Ето вариант 1:

for (int i = 1; i < =n; i++)
        {
            temp = temp* i;

        }

Преведен кодът означава "Започни цикъл за i, като започнеш от i със стойност 1, увеличавай я всеки пък с 1 и приключи цикъла, когато i се изравни с n (в случая сме написали изпълнявай цикъла докато е вярно, че i <=n, което е същото). При всяко преминаване през цикъла умножавай temp със стойността на i. Тоест i става 1,2,3,4... (n-1), а temp съответно става temp* 1, temp*2 (temp е променлива и сме я умножили по 1), temp*3 (temp е променлива и сме я умножили по 1 и 2),.... temp*(n-1) (temp е променлива и сме я умножили по 1,2,3...(n-2) ).". В краят на цикъла temp е умножението на всички стойности от 1 до самото n включително, тоест е n!

Ето вариант 2:

int i = 1;

do

{

 temp = temp * i;

i++;  //(това е равносилно на i = i+1)

 }

while ( i <=n );

Преведен кодът означава "Докато i е по-малко или равно на n, увеличавай i с 1 и умножавай temp със стойността на i. Тоест i става от 1 2,3,4... (n-1), а temp съответно става temp* 1, temp*2 ... temp * (n-1), което отново е n!.".

 

"if yes : извеждам N"

Остава да изведем полученият краен резултат temp (който всъщност е n!) на екрана.

Това правим с :
"Console.WriteLine(temp);"

Преведен кодът означава "Изведи на екрана (принтвай го наричаме) стойността на temp (която е след края на цикъла и съответно е n!)".

Важно е и в двата варианта на цикъла да отбележиш докога точно се изпълняват и защо съм написал "<=n", а не "<=(n-1)".


Ето и съответните кодове:


Вариант 1:

using System;
                    
public class Program
{
    public static void Main()
    {
        int temp = 1;
        int n = int.Parse(Console.ReadLine());
        
for (int i = 1; i <= n; i++)
        {
            temp = temp * i;

        }
        Console.WriteLine(temp);
    }
}

 

Вариант 2:

using System;

public class Program
{
    public static void Main()
    {
        int temp = 1;
        int i = 1;
        int n = int.Parse(Console.ReadLine());

        do
        {

            temp = temp * i;

            i++;  //(това е равносилно на i = i+1)

        }

        while (i <= n);
        Console.WriteLine(temp);
    }
}

 

Ако нямаш Visual Studio на компютъра, можеш да опиташ да ги тестваш в dotnetfiddle.

Ако имаш допълнителни въпроси - давай, не се притеснявай.:)

 

 

1
16/05/2015 01:52:49
eltop avatar eltop 15 Точки

Здравей, Джони!

Ако правило съм разбрала, алгоритъма може би трябва да е нещо такова:

1. n=100, k=1

2.n=n*k

3.k=k+1

4. ako k=100   извеждаме резултата, ако к не е равно на 100 отиваме към стъпка 2.

Поздрави!

0
16/05/2015 01:20:41
JOHNY avatar JOHNY 196 Точки

Привет!

Абсолютно вярно си го написала.:)

 

1
dstefanova avatar dstefanova 67 Точки

Благодаря много, оценявам отделеното време и ще гледам да не е било напразно :) Инсталирано е студиото, готово за употреба, ама още ме е страх да пиша код 

0
JOHNY avatar JOHNY 196 Точки

Изобщо не се притеснявай - досега Visual Studio не е взривил нито един компютър. :)
Започвай да го тормозиш с всички сили и скоро резултата ще е налице.

0
Можем ли да използваме бисквитки?
Ние използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Можете да се съгласите с всички или част от тях.
Назад
Функционални
Използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Използваме „сесийни“ бисквитки, за да Ви идентифицираме временно. Те се пазят само по време на активната употреба на услугите ни. След излизане от приложението, затваряне на браузъра или мобилното устройство, данните се трият. Използваме бисквитки, за да предоставим опцията „Запомни Ме“, която Ви позволява да използвате нашите услуги без да предоставяте потребителско име и парола. Допълнително е възможно да използваме бисквитки за да съхраняваме различни малки настройки, като избор на езика, позиции на менюта и персонализирано съдържание. Използваме бисквитки и за измерване на маркетинговите ни усилия.
Рекламни
Използваме бисквитки, за да измерваме маркетинг ефективността ни, броене на посещения, както и за проследяването дали дадено електронно писмо е било отворено.