Avatar billede tinaw25 Nybegynder
10. april 2014 - 22:10 Der er 12 kommentarer og
1 løsning

Fiinde den samme tal sekvens i et array

Hej

Jeg har siddet og rodet med denne her opgave, og jeg kan simpelthen ikke gennemskue hvordan den skal løses.

Jeg har et 2 arrays.

int[] list1 = {1, 6, 2, 1, 4, 1, 2, 1, 8};
int[] list2 = {1, 2, 1};

Den skal return true, fordi de tal i list2 findes i liste1 i nøjagtig samme talrække.

Min tanke er at jeg skal tjekke begge lister igennem et for loop, også lave en if sætning i det nested for loop der siger hvis list1 == list2.

Men den skal jo tjekke om den samme tal række er lige efter hinden, så hvis den finder 2 eller flere tal som er ens lige efter hinanden er det true. Kan jeg gøre det sådan??

Jeg kan ikke lige gennemskue hvordan det skal gøres, dette er den kode jeg har indtil videre.
Denne kode, return true. Men hvis jeg ændre array list2 til 2, 1, 2 så er den stadigvæk true og det passer jo ikke rigtig.

public static boolean contains(int[] list1, int[] list2)
  {
           
      for(int i = 0; i<list1.length; i++)
      {
             
        for(int j = 0; j<list2.length; j++)
        {
            if(list1[i] == list2[i])
            {
             
                  return true;
             
          }
             
        }
      }
     
      return false; 
     
  }

Jeg ønsker ikke en kode der er bare skrevet, men vil rigtig gerne have nogle hints ellers lære jeg det nok aldrig :-)

/Tina
Avatar billede arne_v Ekspert
10. april 2014 - 22:36 #1
Problemet med din kode er at den returnerer true ved foerste match. Du skal kun returnere true ved alle match.
Avatar billede arne_v Ekspert
10. april 2014 - 22:37 #2
En maade maa vaere kun at returnere false efter den indre for loekke ved ingen match.
Avatar billede arne_v Ekspert
10. april 2014 - 22:38 #3
Den indre for loekke skal ioevrigt nok ikke starte i 0 (raekkefoelge!!).
Avatar billede Slettet bruger
10. april 2014 - 22:49 #4
For at løse opgaven har jeg gjort følgende:

- boolean var sat til false
- for-løkke, som kører hele list1 igennem.
- ArrayList<Integer> til at lægge tal i
- Ny for-løkke som kører liste 2 igennem
- Først i den for-løkke sikrer jeg mig, i+j er mindre end list1.length
- Derefter kigger jeg på, om værdien i list1[i+j] er den samme som i list2[j]
- Hvis den er det lægger jeg værdien i arraylisten
- Hvis ikke, så tømmer jeg listen og breaker ud af løkken
- Efter den if sætning, tjekker jeg, om antallet af elementer i arraylisten er det samme som størrelsen af list2.
Hvis ja, sættes boolean værdien til true og jeg breaker ud af løkken.
- Efter den indre løkke tjekker jeg, om boolean værdien er true, hvis den er, så breaker jeg ud af den ydre løkke. Der er ingen grund til at lede videre.

Og det er det.
Håber ikke at det har gjort opgaven for nem. Den kan løse på mange andre måder, så dette er bare en mulig løsning.
Avatar billede tinaw25 Nybegynder
11. april 2014 - 10:09 #5
ssnielsen:
Hvorfor gør du dette her:  Ser ud som en rigtig god løsning som jeg vil kigge nærmere på :-). Men jeg studser lige over denne her hvorfor gør du det? Først i den for-løkke sikrer jeg mig, i+j er mindre end list1.length??
Avatar billede tinaw25 Nybegynder
11. april 2014 - 10:13 #6
Arne:

Så hvis jeg sætter den indre for lopp til false, hvis der ingen match er. Men jeg kan ikke lige gennemskue hvad næste skridt er??
Avatar billede Slettet bruger
11. april 2014 - 10:50 #7
Jeg tjekker at i+j er mindre end længden på det yderste array, så jeg ikke kigger udenfor arrayets længde og dermed får en array out of bounds exception.

Hvis der ingen match er, så sættes den til false og der brydes ud af den indre løkke og der startes forfra fra næste tal i rækken i den ydre løkke.
Avatar billede tinaw25 Nybegynder
11. april 2014 - 22:49 #8
Smid et svar og takker for hjælpen :-)
Avatar billede Slettet bruger
12. april 2014 - 10:42 #9
Lader til du fandt en løsning, så poster lige min, knap så elegante en, af slagsen:

        int[] list1 = {1, 6, 2, 1, 4, 1, 2, 1, 8};
        int[] list2 = {2,1,2};
       
        boolean answer = false;
        for (int i = 0; i < list1.length; i++)
        {
            ArrayList<Integer> inList = new ArrayList();
            for (int j = 0; j < list2.length; j++)
            {
                if (i+j < list1.length)
                {
                    if (list1[i+j] == list2[j])
                    {
                        inList.add(list2[j]);
                    }
                    else
                    {
                        inList.clear();
                        break;
                    }
                }
                if (inList.size() == list2.length)
                {
                    answer = true;
                    break;
                }
            }
            if (answer == true)
            {
                break;
            }           
        }
        System.out.println("Answer: "+answer);
Avatar billede tinaw25 Nybegynder
13. april 2014 - 18:22 #10
ssnielsen: næh men den virker da.

Men det vil sige at du at du starter på samme måde som mig men inde i det nested for loop.

Siger du at hvis i+j er større end array 1, skal den gå ind i if sætningen og inde i den tjekker du om list[i+j] er == med det i list2 og hvis det er korrekt ligger du tallet i et nyt array.

Men hvad gør du lige i denne her:

  if (inList.size() == list2.length)
                {
                    answer = true;
                    break;
                }


Den løsning havde jeg simpelthen ikke gennemskuet, jeg havde virkelig ikke gennemskuet at man skulle sige i+j og har ikke helt forstået hvorfor man gør det....
Avatar billede Slettet bruger
13. april 2014 - 19:16 #11
Der tjekker jeg bare, at de tal der er fundet er samme mængde, som dem jeg skulle lede efter.
Netop fordi den kan bryde ud af første løkke, hvis der er kommet for langt hen i arrayet, så kan den have fundet to tal ud af tre eller flere og dermed være true. Så det er bare en ekstra sikkerhed.
Avatar billede arne_v Ekspert
16. april 2014 - 04:00 #12
Det boer ikke vaere noedvendig med temporaer data for denne opgave.

Men det er jo altid med lige at faa vendt det hel rigtigt.

Mit andet forseog ser ud som:


    public static boolean contains(int[] list1, int[] list2) {
        for(int i = 0; i < list1.length - list2.length + 1; i++) {
            boolean allmatch = true;
            for(int j = 0; j < list2.length; j++) {
                if(list1[i + j] != list2[j]) {
                    allmatch = false;
                }
            }
            if(allmatch) {
                return true;
            }
        }
        return false;
    }
Avatar billede arne_v Ekspert
16. april 2014 - 04:02 #13
Mit forste forsoeg saa ud som:


    public static boolean contains(int[] list1, int[] list2) {
        outer:
        for(int i = 0; i < list1.length - list2.length + 1; i++) {
            for(int j = 0; j < list2.length; j++) {
                if(list1[i + j] != list2[j]) {
                    continue outer;
                }
            }
            return true;
        }
        return false;
    }


og det virker helt lige som det andet.

Men der er nok nogle som lige skal have checket deres Java bog for mindre kendte features inden man tror paa koden.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester