Премини към съдържанието
Форумът в приложение

По-лесно сърфиране. Научи повече.

Kaldata.com - Форуми

Приложение на форума на цял екран с push известия, значки и други.

За да инсталирате това приложение на iOS и iPadOS
  1. Докоснете Иконата за споделяне в Safari
  2. Превъртете менюто и докоснете Добавяне към началния екран.
  3. Докоснете Добавяне в горния десен ъгъл.
За да инсталирате това приложение на Android
  1. Докоснете менюто с 3 точки (⋮) в горния десен ъгъл на браузъра.
  2. Докоснете Добавяне към началния екран или Инсталиране на приложение.
  3. Потвърдете, като докоснете Инсталиране.

Добре дошли!

Добре дошли в нашите форуми, пълни с полезна информация. Имате проблем с компютъра или телефона си? Публикувайте нова тема и ще намерите решение на всичките си проблеми. Общувайте свободно и открийте безброй нови приятели.

Моля, регистрирайте се за да публикувате тема и да получите пълен достъп до всички функции.

 

Проблем със задача

Featured Replies

Идеята е да напиша 2 числа в конзолата и да ми изведе всичките числа между тях, които при деление на 5 имат остатък 0.
Това е моето решение, обаче, когато написах 1 и 5, отговорът ми беше 1.
 
package introtojava;
 
import java.util.Scanner;
 
public class PrintingFormattedDates {
 
 
public static void main(String[] args)  {
Scanner input = new Scanner(System.in);
int a = input.nextInt();
int b = input.nextInt();
int c=0;
for (a=(a+1);a<b;a++);
{
if (a%5==0)
c++;
else c=c;
 
}
System.out.println©;
 
 
 
 
}
}
 
Къде ми е грешката ?
     

 

...

 

1) 

for (a=(a+1);a<b;a++);

Цикъла, написан по този начин ще направи точно нищо с блока, към който уж е закачен. Следователно, цикъла си цикли, а се променя, но блока ще се изпълни едва, когато а стане равно на b-1;

2)

if (a%5==0)
c++;
else c=c;

Защо увеличаваме c, само когато а се дели на 5 без остатък ? Освен това, 

c = c;

е безсмислено и абсурно написан код. Просто няма да имаме else клауза.

3)

System.out.println(c);

Това е дори извън тялото на предполагаемото тяло за цикъла - т.е. дори да има отговор(и), то ще бъде отпечатан последния (или в нашия случай, по - скоро ще се изпечата броя на числата, делими на 5 без остатък).

 

4) Когато се работи с потоци, правилото е винаги да се затварят - Scanner-а е Wrapper обект на System.in потока. Като такъв, той трябва да се затвори след използването си.

 

Прилагам примерна имплементация на програмата, защото коригирането на този код ще изисква поне 70% от него да се затрие и без това:

public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		int a = input.nextInt();
		int b = input.nextInt();
		int c = 0;
		for (a = (a + 1); a < b; a++) {
			if (a % 5 == 0) {
				c++;
				System.out.print(a + " ");
			}
		}
		System.out.println("\nБрой на цисла, делящи се на 5 без остатък: " + c);
		input.close();
	}

Прегледайте какви са поправките по кода и ги приложете и за Вашия случай.

 

Поздрави !

 

P.S. Една добра, допълнителна идея е да се направи и проверка за a < b още в началото. И ако се окаже, че това не е изпълнено, или да се разменят стойностите и тогава да се търсят делители, или програмата да казва, че са въведени невалидни стойности ...

Редактирано от soundtracker (преглед на промените)

Какво ще кажеш да заменим

 

int c=0;
for (a=(a+1);a<b;a++);
{
if (a%5==0)
c++;
else c=c;
 
}
System.out.println©;

 

със

 

...
for (int i = (a + 1); i < b; i++)
{
    if (i % 5 == 0)
    {
        System.out.println(i);
    }
}
...
М?

Какво ще кажеш да заменим
 

int c=0;
for (a=(a+1);a<b;a++);
{
if (a%5==0)
c++;
else c=c;
 
}
System.out.println©;

 
със
 
...
for (int i = (a + 1); i < b; i++)
{
    if (i % 5 == 0)
    {
        System.out.println(i);
    }
}
...
М?

 


Поне в приложения код, 'а' не се използва след цикъла. Ако не му е необходимо повече, няма проблем да си го променя.
Не е много препоръчително, но и с промяна на 'а' ще си сработи.
Тъй като запитващия обаче е начинаещ, съм по - склонен да се съглася с Вашето предложение.

Редактирано от soundtracker (преглед на промените)

Писали сме заедно. Въпросът ми беше към radgx.

Тази променлива "c", която се инициализира с 0 и се инкременрира при всеки модулус 5 равен на нула, ще изведе офсета на кратното 5 число след стойността на "а", а не самото кратно на 5 число (както е по условие).

Инак съм съгласен, по-добре за сигурността на кода е, за итерационна променлива да се използва новодекларирана променлива, която обслужва само цикъла. Ако беше използвал такава, не компилатора, а още интелисенса на IDE-то, щеше да се разпищи за терминиращия оператор ";" на реда дефиниращ цикъла и нямаше да се стигне до такова положение.

П.П. В този форум винаги е царяла леката и свободна атмосфера на неофициалното общуване. Ако нямаш нищо напротив, предлагам да си говорим на ти.

  • Автор

1) 

for (a=(a+1);a<b;a++);

Цикъла, написан по този начин ще направи точно нищо с блока, към който уж е закачен. Следователно, цикъла си цикли, а се променя, но блока ще се изпълни едва, когато а стане равно на b-1;

2)

if (a%5==0)
c++;
else c=c;

Защо увеличаваме c, само когато а се дели на 5 без остатък ? Освен това, 

c = c;

е безсмислено и абсурно написан код. Просто няма да имаме else клауза.

3)

System.out.println(c);

Това е дори извън тялото на предполагаемото тяло за цикъла - т.е. дори да има отговор(и), то ще бъде отпечатан последния (или в нашия случай, по - скоро ще се изпечата броя на числата, делими на 5 без остатък).

 

4) Когато се работи с потоци, правилото е винаги да се затварят - Scanner-а е Wrapper обект на System.in потока. Като такъв, той трябва да се затвори след използването си.

 

Прилагам примерна имплементация на програмата, защото коригирането на този код ще изисква поне 70% от него да се затрие и без това:

public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		int a = input.nextInt();
		int b = input.nextInt();
		int c = 0;
		for (a = (a + 1); a < b; a++) {
			if (a % 5 == 0) {
				c++;
				System.out.print(a + " ");
			}
		}
		System.out.println("\nБрой на цисла, делящи се на 5 без остатък: " + c);
		input.close();
	}

Прегледайте какви са поправките по кода и ги приложете и за Вашия случай.

 

Поздрави !

 

P.S. Една добра, допълнителна идея е да се направи и проверка за a < b още в началото. И ако се окаже, че това не е изпълнено, или да се разменят стойностите и тогава да се търсят делители, или програмата да казва, че са въведени невалидни стойности ...

Копирах точно кода, който беше написал 

package introtojava;

import java.util.Scanner;

public class PrintingFormattedDates {


	public static void main(String[] args)  {
		Scanner input = new Scanner(System.in);
		int a = input.nextInt();
		int b = input.nextInt();
		int c = 0;
		for (a = (a + 1); a < b; a++) {
			if (a % 5 == 0) {
				c++;
				System.out.print(a + " ");
			}
		}
		System.out.println("\nБрой на цисла, делящи се на 5 без остатък: " + c);
		input.close();
	}
}
     

Не се получава.

Другото, което е: Защо трябва 

System.out.println (c); 

да ни е в цикъла:

...
for (int i = (a + 1); i < b; i++)
{
    if (i % 5 == 0)
    {
        System.out.println(i);
    }
}
...

Аз не търся числата а бройката им.

За това:

else c=c;

мислех, че задължително във if-a трябва да покажем какво става във обратния случай.

Следващия ми въпрос е :

input.close();

Каква е идеята на този ред ? Аз лично не съм го срещал.

Не мога да разбера къде ми е грешката:

package introtojava;

import java.util.Scanner;

public class PrintingFormattedDates {


	public static void main(String[] args)  {
		Scanner input = new Scanner(System.in);
		int a = input.nextInt();
		int b = input.nextInt();
		int c = 0;
		for (a = (a + 1); a < b; a++) {
			if (a % 5 == 0) {
				c++;
			}
		}
		System.out.println(c);
	}
}
   

Иначе грешката ми е ясна. Просто съм въвеждал a>b и е напълно нормално да ми извежда 0. 

...

Аз не търся числата а бройката им.

...

Ето тук,

Идеята е да напиша 2 числа в конзолата и да ми изведе всичките числа между тях, които при деление на 5 имат остатък 0.

...

си написал друго! Затова си получил такова предложение ;) Ако вместо "изведе всичките числа между тях", беше написал "изведе броя на числата между тях", щеше да получиш друго предложение :)

  • Автор

Виновен съм :D Моя е грешката за което се извинявам :)

Копирах точно кода, който беше написал 

package introtojava;

import java.util.Scanner;

public class PrintingFormattedDates {


	public static void main(String[] args)  {
		Scanner input = new Scanner(System.in);
		int a = input.nextInt();
		int b = input.nextInt();
		int c = 0;
		for (a = (a + 1); a < b; a++) {
			if (a % 5 == 0) {
				c++;
				System.out.print(a + " ");
			}
		}
		System.out.println("\nБрой на цисла, делящи се на 5 без остатък: " + c);
		input.close();
	}
}
     

Не се получава.

//Soundtracker: Кое точно не се получава ? И самите числа се изписват, и броя им се извежда накрая - последния System.out.println, който дори е на български си казва какво е ...

 

Другото, което е: Защо трябва 

System.out.println (c); 

да ни е в цикъла:

//Soundtracker: Защото условието подсказваше, че се искат и числата - колегата @darkterminal Ви е дал същото мнение. Т.е. условието е подвеждащо в случая, но реших да направя и двете. Затова имаме както принтиране на числата, така и принтиране на бройката им.

...
for (int i = (a + 1); i < b; i++)
{
    if (i % 5 == 0)
    {
        System.out.println(i);
    }
}
...

Аз не търся числата а бройката им.

За това:

else c=c;

мислех, че задължително във if-a трябва да покажем какво става във обратния случай.

//Soundtracker: Не, if може да съществува и самостоятелно, без else. От друга страна, не е възможно да имаме else, без да имаме предходящ if оператор

 

Следващия ми въпрос е :

input.close();

Каква е идеята на този ред ? Аз лично не съм го срещал.

//Soundtracker: Това, че не сте го срещал, не означава, че не трябва да го има. 

Както Ви споделих и в първото си мнение, всеки входящ или изходящ поток в програмата Ви, трябва да се затваря, след като се използва.

InputStream.close() е именно метода, който го прави.

 

Не мога да разбера къде ми е грешката:

...

Иначе грешката ми е ясна. Просто съм въвеждал a>b и е напълно нормално да ми извежда 0. 

//Soundtracker: Ами не само - обърнете внимание и на останалите проблеми - където затваряте цикъла с ";", като по този начин тялото се изпълнява като instance блок, вместо като тяло на цикъл.

Затварянето на потоци специално за този код не е фатален, но е проблем откъм ползване на ресурси в програмата Ви. Ще отбележим и липсата на проверка на аргументите, което път се оказва първопричината за запитването.

Допълнително, както стана вече ясно, условието се интерпретира по повече от един начин и ако сложим и идеята за листване и на числата, се получават още 2 проблема. 

 

Попълних директно по Вашите запитвания коментарите си.

 

Поздрави !

  • Автор

Както Ви споделих и в първото си мнение, всеки входящ или изходящ поток в програмата Ви, трябва да се затваря, след като се използва.

InputStream.close() е именно метода, който го прави. 

//Това не го разбрах. 

  • Автор

И още един въпрос за да не правя нова тема. 

Задачата е следната:

 Напишете програма, която чете пет числа и отпечатва най-голямото от тях

Със if я реших, обаче не знам как да я направя със for.

 

Както Ви споделих и в първото си мнение, всеки входящ или изходящ поток в програмата Ви, трябва да се затваря, след като се използва.

InputStream.close() е именно метода, който го прави. 

//Това не го разбрах. 

 

На първия ред от програмата си, Вие пишете следното:

Scanner input = new Scanner(System.in);

Следвайки въпроса Ви, имам чувството, че и сам не осъзнавате какво всъщност върши това нещо.

Scanner е wrapper клас. Той обвива обекти, които се ползват за изчитане на данни от потоци, файлове, символни низове и прочие. 

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

Wrap-вайки класа на System.in, ето какво прави Scanner конструктора:

public Scanner(InputStream source) {
        this(new InputStreamReader(source), WHITESPACE_PATTERN);
    }

Т.е. той ще създаде reader обект към потока, който след това ще е отворен за изчитане.

Дотук добре, четем, четем и след един момент, вече не е нужно да четем данни от този поток.

Когато един поток или reader не е нужен за изчитането на още данни, то той трябва да се затвори. Причините за това са достатъчно - първо, всеки ресурс, който се ползва, трявба да се освобождава, отварянето на множество потоци към един и същ файл е предпоставка за доволно голям брой проблеми, започвайки от липса на данни и стигнем до проблеми с concurency достъпа до ресурса от много точки на програмата ни.

В предното си мнение Ви споделих и това:

 

 

Затварянето на потоци специално за този код не е фатален, но е проблем откъм ползване на ресурси в програмата Ви. 

така, че това причината останалите колеги да не Ви обърнат внимание за това.

 

Относно втория Ви въпрос - отново не е много ясно какво е условието и какво се опитвате да направите - принципно е възможно задачата да се реши без if, но това ще изиска или ползването на тернарен оператор или една малко особена гимнастика с числата. Ще приложа решения както с тернарен оператор, така и решението без използване на условен оператор.

 

Решение, без използване на оператор за условие "if" или "? :" :

import java.util.Scanner;

public class LargestOfFive {
    
    private static final int SIZE_NUMBERS = 5;
    
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int[] numbers = new int[SIZE_NUMBERS];
        for (int i = 0; i < SIZE_NUMBERS; i++) {
            numbers[i] = sc.nextInt();
        }
        int greatest = numbers[0];
        for (int i = 1; i < SIZE_NUMBERS; i++) {
            //Намери разликата между двете числа за сравнение
            int diff = greatest - numbers[i];
            //Определи знака на получената разлика - дали е "+" или "-"
            int signum = (diff >> 31) & 0x1; // (Минус ще е 1-ца, плюс ще е 0-ла)
            //Добави, ако разликата е < 0 -> това означава, че numbers[i] е по-голямо от 
            //текущото greatest.
            greatest = greatest - signum * diff;
        }
        System.out.println(greatest);
        sc.close();
    }

Решение с използване на тернарен оператор:

import java.util.Scanner;

public class LargestOfFive {
    
    private static final int SIZE_NUMBERS = 5;
    
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int[] numbers = new int[SIZE_NUMBERS];
        for (int i = 0; i < SIZE_NUMBERS; i++) {
            numbers[i] = sc.nextInt();
        }
        int greatest = numbers[0];
        for (int i = 1; i < SIZE_NUMBERS; i++) {
            greatest = greatest < numbers[i] ? numbers[i] : greatest;
         }
        System.out.println(greatest);
        sc.close();
    }
}

Поздрави !

Редактирано от soundtracker (преглед на промените)

  • Автор

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

Няма да се притесняваш мой човек. Статистиката сочи, че средно след 10 000 часа работа в дадено направление, човек става професионалист. Това са около 5 години. Залягаш, четеш и се упражняваш със страст и желание и след около 5 години от сивото и рошаво пате, ще излезе голям бял и красив лебед! Не се отказвай и дерзай!

 

Успех!

Ето ти и дръг поглед върху нещата. Намираш първото X число от интервала което е кратно на 5. Да речем интервала ти е зададен (5, 150], където K = 5, N = 150.  След като намериш първата стойност на X започваш да итерираш докато X <= N, печаташ X и увеличаваш стойността на X с 5. Така всеки път ще получаваш кратно на 5 число ;) Ето ти псевдокод: 

K = 5
N = 150
X = K
while (++X % 5);
while (X <= N) {
    print X
    X += 5
}

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

Това е нормално. Колегата @darkterminal Ви го е казал - с търпение, постоянство, любопитство и усърдие, нещата ще се получат. 

Важното е мотивация и постоянство - останалото така или иначе ще дойде :). Питайте, интересувайте се, дискутирайте - форумите са именно за това - за взаимопомощ и обмяна на мнения.

 

Поздрави !

Архивирана тема

Темата е твърде стара и е архивирана. Не можете да добавяте нови отговори в нея, но винаги можете да публикувате нова тема, в която да продължи дискусията. Регистрирайте се или влезте във вашия профил за да публикувате нова тема.

Разглеждащи това в момента 0

  • Няма регистрирани потребители разглеждащи тази страница.

Дарение

  • Подкрепи съществуването на форума - направи дарение
    32%
    Дарени 315 € от нужните 1 000 €

Бюлетин

Получавайте известие, когато има важна промяна или новина свързана с форума.

Профил

Навигация

Търсене

Търсене

Конфигуриране на push известия в браузъра

Chrome (Android)
  1. Докоснете иконата на катинар до адресната лента.
  2. Докоснете Разрешения → Известия.
  3. Променете предпочитанията си.
Chrome (Desktop)
  1. Кликнете върху иконата на катинар в адресната лента.
  2. Изберете Настройки на сайта.
  3. Намерете Известия и коригирайте предпочитанията си.