Loading...
BorisYordanov avatar BorisYordanov 1 Точки

Решение на задача от Глава 7 - Масиви във "Въведение в програмирането със C#"

Линк към главата

Имам въпрос за решението задача №4, с условие:

"4.      Напишете програма, която намира максимална редица от последова­телни еднакви елементи в масив. Пример: {2, 1, 1, 2, 3, 3, 2, 2, 2, 1} à {2, 2, 2}."

По-долу съм сложил и решение, което свалих от сайта.

Имам проблем със следната част от кода:

 for (int count = 0; count < arrayLength; count++)
            {
                int currentCount = 0;
                for (int minCount = count; minCount < arrayLength; minCount++)
                {
                    if (arrayOfNumbers[count] == arrayOfNumbers[minCount])

Очевидно е, че count и minCount винаги ще имат една и съща стойност, но идеята на задачата е програмата ни да сравнява един член от масива със следващия, т.е. да сравним елемент 0 с елемент 1, а след това елемент 1 с елемент 2. А в момента (доколкото разбирам сравняваме един и същ, понеже

arrayOfNumbers[0] == arrayOfNumbers[0])  

arrayOfNumbers[1] == arrayOfNumbers[1]) 

и т.н.

Но решението работи както трябва и е ясно, че аз нещо ме съм разбрал. Може ли някой да ми изясни как точно работи това решение?

using System;

class FindsTheMaximalSequence
{
    static void Main(string[] args)
    {
        string enterLength = Console.ReadLine();
        int arrayLength = int.Parse(enterLength);
        int[] arrayOfNumbers = new int[arrayLength];
        string enterString;
        for (int count = 0; count < arrayLength; count++)
        {
            enterString = Console.ReadLine();
            arrayOfNumbers[count] = int.Parse(enterString);
        }
        int maxCount = 0;
        int value = 0;
        for (int count = 0; count < arrayLength; count++)
        {
            int currentCount = 0;
            for (int minCount = count; minCount < arrayLength; minCount++)
            {
                if (arrayOfNumbers[count] == arrayOfNumbers[minCount])
                {
                    currentCount++;
                    if (maxCount < currentCount)
                    {
                        maxCount = currentCount;
                        value = arrayOfNumbers[count];
                    }
                }
                else
                {
                    break;
                }
            }
        }            
        Console.WriteLine("Max length = {0} and value is {1}", maxCount, value);                        
    }
}

 

Тагове:
0
Programming Basics
sider.topalov avatar sider.topalov 38 Точки
Best Answer

Здравей, ще се опитам да ти го обясня максимално упростено.

Така преди 2-та "for" цикъла имаме 2 променливи с цел в "maxCount" да записваме най-дългата редица,а в "value" да запишем кой индекс от масива отговаря на тая дължина примерно ще ползвам твоя масив по горе и индекса ни е "2". 

Така след като влезнем в първия цикъл, отново имаш променлива "currentCount" value = "0" вътре след първия "for" тя ще ни служи за текущата дължина на дадена поредица и искаме тази променлива всеки път да започва от "0" за да може да броим следващата дълцина на текущата поредица от масива. След това влизаме във втория "for" и казваме "minCount = count" с цел да се подсигурим, че нашия втори цикъл винаги ще започва от индекса на първия тоест ако "count = 4"  в даден момент то ние искаме нашия "minCount" също да има тая стойност "4" защото ние вече сме обходили предните индекси "3,2,1 и 0".

И след това влизаме в тялото на втория "for" и там имаме която проверява "arrayOfNumbers[count] == arrayOfNumbers[minCount]"

нека кажем, че "count = 1" и "minCount = 1"  тогава нашия "arrayOfNumbers[count] и arrayOfNumbers[minCount]" => "1 == 1" тогава "if" връща "true" и влиза вътре и увеличава "currentCount"  с "1"  и там има още един "if" който проверява дали "maxCount" не е по малка от текущата дължина "currentCount"  и ако е то тогава присвояваме на "maxCount = currentCount" и на "value = arrayOfNumbers[count]" все едно "value = 1" и завъртаме втория "for" и правим същите стъпки наново  "arrayOfNumbers[count] == arrayOfNumbers[minCount]" тоест => index(1) със стойност (1) от масива дали е равна(=) на index(2) със стойност(пак 1) от масива връща true и продължава по същия начин по горе. Но в момента в който нашия вътрешен "for" стигне да речем index(3) със стойност(2) в масива и тръгне да проверява "arrayOfNumbers[count] == arrayOfNumbers[minCount]" тоест => index(1) със стойност (1) от масива дали е равна(=) на index(3) със стойност(2) от масива и върне "false" бреаква нашия вътрешен цикъл връща се на първия "for" увеличава индекса и така продължава докато не стигне до края на масива след което ти вече имаш "maxCount = 3" и "value = 2" и като имаш тези две неща с един for цикъл от 0 до maxCount  да принтираш value.

Е това е от мен надявам се съм ти го обяснил до толкова че да ме разбереш от това по просто обяснение честно казано не мисля че мога да дам и все пак ако нещо не ти е станало ясно питай смело. Успех! :)

1
23/05/2016 14:08:34
DStefanow avatar DStefanow 112 Точки

Според мене това решение е бая сложно (като се има предвид двата вложени цикъла), аз лично го правя с едно обхождане, като count = 1, и карам от нулевия елемент на масива от array.Length - 1, и на всяка итерация от цикъла сравнявам дали съм намерил по- голяма подредица от предходната и от там нататък става лесно, ако искам най- лявата подредица в if-a сравнявам с ' > ', ако целта ми е най- дясната ' >= '.

0
Nikola_Andreev avatar Nikola_Andreev 671 Точки

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

Първият цикъл започва от 0. Влизаме в него и започва вторият цикъл и той също е от 0. Този втория обаче ще се извърти от 0 до дължината на масива (10 примерно), а първия си стой на 0. Първият масив ще стане 1 чак когато се извърти втория. И общо взето получаваме 10 пъти въртене от 1 до 10 (ако масива е от 10 елемента). Едва ли ще ти стане ясно веднага, но най-просто казано първо се извърта вътрешния цикъл и чак тогава продължава въртенето на външния. Пусни си го през дебъгера, ако можеш да дебъгваш и изгледай някое видео където се обясняват вложени цикли и ще ти стане по ясно.

Поздрави.

0
BorisYordanov avatar BorisYordanov 1 Точки

Знам какво е вложен цикъл, но не бях разбрал, че така работят (първо се извърта втория, а после първия). Благодаря за информацията!

0
KrasimirPetkov avatar KrasimirPetkov 328 Точки

Задачата може да се реши с един for-цикъл, който да обходи масива.

Необходимата информация, за извеждане на резултат е:

1. Най-големият брой еднакви елементи.

2. Началната им позиция в масива.

Това означава, че имаме нужда от две променливи: maxCount и maxStart.

За целта може да сравним последователно всеки елемент от масива с предходния, като началният индекс се съхранява в променлива currentStart, а броя на еднаквите елементи в currentCount. При всяка промяна на currentCount, сравняваме currentCount с maxCount и ако е по-голям, присвояваме стойностите към maxCount и maxStart. Ако елементът е различен от предходните, currentCount се връща в изходна позиция, а currentStart става еквивалентен на настоящия индекс.

int maxCount = 0;
int maxStart = 0;
int currentCount = 1;
int currentStart = 0;
for (int i = 1; i < array.Length; i++)
{
    if (array[i]==array[i-1])
    {
        currentCount++;
        if (currentCount > maxCount) { maxCount = currentCount; maxStart = currentStart; }
    }
    else
    {
        currentCount = 1;
        currentStart = i;
    }
}

Ето и линк към решението (масивът се въвежда на един ред, разделен с интервали):

http://pastebin.com/wPqkkyMw

PS: Използвал съм малко Linq, което не се учи в Programming Basics, но това е само с цел по-лесно въвеждане на изходните данни и извеждане на резултата. Можеш да го замениш с каквото намериш за удачно :)

1
23/05/2016 16:47:21
BorisYordanov avatar BorisYordanov 1 Точки

Твоето решение наистина е доста по-опростено. Благодаря

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