Kirjautuminen

Haku

Tehtävät

Keskustelu: Koodit: Java: Lukujono

JRokka [09.11.2019 19:37:14]

#

Tässä ohjelmassa päätellään käyttäjän antamien syötteiden perusteella, voidaanko lukujono muodostaa. Lukujonoa on tässä ohjelmassa kahta eri tyyppiä, joko lisätään tai kerrotaan samalla luvulla.

Koodi

import java.util.Scanner;
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author jonir
 */
public class Lukujono {
    public static void main(String[] args){
        Scanner syote = new Scanner(System.in);
        int luku_1 = 0;
        int luku_2 = 0;
        int luku_3 = 0;
        int luku = 0;
        int luvut = 0;
        //Syötetään lähtötiedot.
        System.out.println("Syötä kolme lukua.");
        luku_1 = syote.nextInt();
        luku_2 = syote.nextInt();
        luku_3 = syote.nextInt();
        System.out.println("Syötä lukujen määrä.");
        luvut = syote.nextInt();
        //Päätellään, muodostuuko näistä lukujono.
        if (luku_2 - luku_1 == luku_3 - luku_2){
            luku = luku_2 - luku_1;
            //Lukujonoja saadaan jatkettua, kun lisätään aina samalla luvulla.
            for (int x = 3; x < luvut; x++){
                luku_3 += luku;
                System.out.println(luku_3);
            }
        }
        if (luku_2 / luku_1 == luku_3 / luku_2){
            luku = luku_2 / luku_1;
            //Lukujonoja saadaan jatkettua, kun kerrotaan aina samalla luvulla.
            for (int x = 3; x < luvut; x++){
                luku_3 *= luku;
                System.out.println(luku_3);
            }
        }
    }
}

Tronic [10.11.2019 09:42:43]

#

Pythonilla tehtynä. Syötteen pituus saa olla minkä hyvänsä mittainen ja lisäsin tähän myös Fibonaccin lukujonot.

numbers = [
    int(n) for n in input("Lukujonon alku välilyönneillä erotettuna: ").split()
]
# Using any two values a and b, calculate the next value
rules = [
    lambda a, b: b + b - a,   # Arithmetic
    lambda a, b: b * b / a,   # Geometric
    lambda a, b: a + b,       # Fibonacci
]
for rule in rules:
    # Test if the rule matches
    a, b, *rest = numbers
    for n in rest:
        if n != rule(a, b): break
        a, b = b, n
    else:
        # Rule matched, generate a series
        out = numbers[:2]
        for i in range(8):
            out += rule(out[-2], out[-1]),
        print(out)

Metabolix [10.11.2019 10:20:21]

#

Alkuperäisessä koodissa on pari merkittävää vikaa.

Ensinnäkin jakolaskun tekeminen kokonaisluvulla johtaa väärään tulokseen jakolaskusäännön soveltamisessa. Esimerkiksi luvut 1, 2, 5 jatkuvat kahdella kertoen 10, 20, 40, 80, ja luvut 2, 3, 5 jatkuvat yhdellä kertoen 5, 5, 5. Pyöristysvirheiden välttämiseksi kokonaisluvuilla a/b == c/d kannattaa muuttaa kertolaskuksi normaalien matematiikan sääntöjen mukaan: a*d == b*c.

Toiseksi tuossa else-sanan puuttumisen vuoksi lasketaan ensin lukuja ensimmäisellä säännöllä ja vasta sitten tarkastetaan toisen säännön toimivuus, joten on mahdollista, että lukujonoa jatketaan kahteen kertaan. Virheenä on siis sekä väärä määrä lukuja että epälooginen lukujono. Vika on helpointa nähdä isoilla luvuilla, joilla jakolaskun tulos on 1 jo edellä kuvatusta jakolaskuvirheestä johtuen. Ohjelma tuottaa siis esimerkiksi 6 luvun lukujonon 101, 102, 103, 104, 105, 106, 106, 106, 106. Pienemmistä luvuista löytyy 5 luvun lukujono 1, 3, 5, 7, 9, 27, 81 ja vaikkapa 6 luvun lukujono 1, 4, 7, 10, 13, 16, 64, 256, 1024.

Muuttujat on siistimpää esitellä vasta käyttöpaikalla. Osa näistä voisi olla myös vakioita. Tässä tapauksessa erityisesti syötteet voi laittaa vakioiksi, jotta ei tule sitä virhettä, että toinen lukujono jatkuisi ensimmäisen lopusta.

final int luku_1 = syote.nextInt();

Siisteyden vuoksi kannattaa poistaa koodin alusta editorin automaattiset kommentit – on aika pöljää kopioida niitä ympäriinsä.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta