Page 1 of 2 12 Last
  • Jump to page:
    #1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2013
    Posts
    37
    Rep Power
    1

    I don't understand why my program isn't working


    This program is supposed to compare two arrays, loop through them, and check to see if all elements are equal. If all elements are equal, I return a 1, if not, return a 0.

    This is it:
    Code:
    #!/usr/bin/env perl
    use warnings;
    
    my @array_a = qw(1 2 3 4);
    my $ref = \@array_a;
    my @array_b = qw(1 2 3 4);
    my $ref2 = \@array_b;
    
    sub Compare {
            my($arrayref, $arrayref2) = @_;
    
            foreach my $j(@$arrayref){
                    foreach my $i(@$arrayref2){
                            if($j == $i){
                            next;
                            return 1;
                            }
                            else{return 0;}
    I don't see why this code isn't working. The function takes in two references to arrays, loops through them, comparing them, when they are equal, I go to the next iteration of the loop. If any aren't equal, immediately return 0. Problem is that I keep getting 0 returned no matter what. The only way I could see that I'm making an error is if the next function isn't working the way I think it should be
    What do y'all think?

    Also, as a curiousity, I was wondering, how can I compare all elements of an array, whether it's a string or a scalar. As it stands, my program only works with scalars, I want it to be able to look through any data type.
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Apr 2009
    Posts
    1,873
    Rep Power
    1225
    For comparing arrays it would be best to use the Array::Compare module.

    Another option would be to simply to do a direct comparison - no need to do any looping.
    Code:
    if ("@array1" eq "@array2") {
        # they are equal - do something
    }
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2013
    Posts
    37
    Rep Power
    1
    Originally Posted by FishMonger
    For comparing arrays it would be best to use the Array::Compare module.

    Another option would be to simply to do a direct comparison - no need to do any looping.
    Code:
    if ("@array1" eq "@array2") {
        # they are equal - do something
    }
    It's a function I'm trying to create within a program and, unfortunately, my professor wants me to do it this way. It's supposed to be tediously annoying like that. XD
    You don't see why it's not working?

    Thanks for the response Fish.
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2013
    Posts
    37
    Rep Power
    1
    also, I rearranged the function a little bit, and I got caught in an infinite loop, if that helps :

    Code:
    sub Compare {
            my($arrayref, $arrayref2) = @_;
    
            foreach my $j(@$arrayref){
                    foreach my $i(@$arrayref2){
                            while($j == $i){
                            print "It's true\n";
                            }
                    }
            }
    }
    It prints it's true forever. Why doesn't the loop terminate when it reaches the conclusion?
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Apr 2009
    Posts
    1,873
    Rep Power
    1225
    So, your instructor wont let you use the module and requires you to use 1 or more loops. No problem.

    First compare their size. If they're not the same, return 0.

    Next use a single loop 0..$size (size is the number of indexes) and compare the values of those array indexes. If they differ, return 0.

    If you successfully reach the end of the arrays, return 1.
  10. #6
  11. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Apr 2009
    Posts
    1,873
    Rep Power
    1225
    It prints it's true forever. Why doesn't the loop terminate when it reaches the conclusion?
    Because you created an infinite loop here:
    Code:
    while($j == $i){
  12. #7
  13. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2013
    Posts
    37
    Rep Power
    1
    Originally Posted by FishMonger
    Because you created an infinite loop here:
    Code:
    while($j == $i){
    So a loop doesn't terminate once you reach the end of both arrays? What is it comparing after it reaches the end? Both arrays only have 4 elements.
  14. #8
  15. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Apr 2009
    Posts
    1,873
    Rep Power
    1225
    You're not looping over the entire array. Since $j and $i never change inside that while block, it says inside that block forever printing your "It's true\n" statement. Instead of a while block you need to use an if block.
  16. #9
  17. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2013
    Posts
    37
    Rep Power
    1
    Originally Posted by FishMonger
    You're not looping over the entire array. Since $j and $i never change inside that while block, it says inside that block forever printing your "It's true\n" statement. Instead of a while block you need to use an if block.
    Okay, I have went a new direction with this program, Fish. Check it, yo.

    #!/usr/bin/env perl
    use warnings;

    Code:
    my @array_a = qw(1 2 3 4 5);
    my $ref = \@array_a;
    my @array_b = qw(1 2 3 4 5);
    my $ref2 = \@array_b;
    
    sub Compare {
            my($arrayref, $arrayref2) = @_;
            my $arraysize1 = scalar(@$arrayref);
            my $arraysize2 = scalar(@$arrayref2);
    
            if($arraysize1 == $arraysize2){
                  for(my $count = 1; $count <= $arraysize1; $count++){
                        foreach my $j(@$arrayref){
                             foreach my $i(@$arrayref2){
                                if($j == $i){
                                    if($count < $arraysize1){
                                        next;}
                                    else{return 1;}
                                }
                                else{return 0;}
                              }
                        }
                   }
            }
            else{return 0;
            }
    }
    
    my $z = Compare($ref, $ref2);
    print $z;
    LEt me explain the function. It starts off by getting the number of elements of both arrays being passed in, putting it into two variables 'arraysize1', 'arraysize2'.

    Next I start a loop that will iterate for the length of the array.

    Now if the element of array1 = array 2, I move to the next iteration of the loop, if it doesn't, I return 0. If the count is on the last element of the arrays, than next is skipped return 1.

    Though I say all this, this code doesn't work. This must mean that I am misusing some piece of code, or I have made some error that I am missing. With all those loops, I wouldn't really be surprised.
  18. #10
  19. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Apr 2009
    Posts
    1,873
    Rep Power
    1225
    Since this is for a class assignment, I can't show you the solution. I can only give you hints.

    You only need 1 loop, not 3 nested loops.
  20. #11
  21. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Jun 2012
    Posts
    776
    Rep Power
    495
    And you also need only one loop variable. I wish to remind you that array indices start at 0, not 1 and that the index of the last element is therefore one less that the array size (I am saying that because your $count variable does not follow this logic).

    Your code is far far too complicated for what you need to do. I don't want to give a coded solution for the same reason as Fishmonger, but try to think about it: you have two arrays which you know to be the same size (because you've checked just before). Say this size is N.

    If you have a variable $i iterating on every integer value between 0 and N-1, you can just compare $array1[$i] with $array2[$i] for each value of $i. Return 0 (which exists the loop) if they are not equal. And return 1 if you reach the end of the loop. And you are DONE. That takes two lines of code.
  22. #12
  23. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Apr 2009
    Posts
    1,873
    Rep Power
    1225
    Additional hint, the body of the loop is only 1 line of code.
  24. #13
  25. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2013
    Posts
    37
    Rep Power
    1
    Originally Posted by Laurent_R
    And you also need only one loop variable. I wish to remind you that array indices start at 0, not 1 and that the index of the last element is therefore one less that the array size (I am saying that because your $count variable does not follow this logic).

    Your code is far far too complicated for what you need to do. I don't want to give a coded solution for the same reason as Fishmonger, but try to think about it: you have two arrays which you know to be the same size (because you've checked just before). Say this size is N.

    If you have a variable $i iterating on every integer value between 0 and N-1, you can just compare $array1[$i] with $array2[$i] for each value of $i. Return 0 (which exists the loop) if they are not equal. And return 1 if you reach the end of the loop. And you are DONE. That takes two lines of code.

    Gosh, I didn't think about it like that at all. HAHA. That is indeed much simpler. This new one works:

    Code:
    Sub Compare{
            my($arrayref, $arrayref2) = @_;
            my $arraysize1 = scalar(@$arrayref);
            my $arraysize2 = scalar(@$arrayref2);
    
            if($arraysize1 == $arraysize2){
                  for(my $count = 0; $count < $arraysize1; $count++){
                         if(@$arrayref[$count] !=  @$arrayref2[$count]){
                                    return 0;
                         }
                  }
                  return 1;
            }
    
            else{return 0;
            }
    }
    my $z = Compare($ref, $ref2);
    print $z;

    But why wasn't the other one working? It will bother me all day. Even if I adjust the count it wouldn't work.

    You the man, LAurent, I've been messing with this code for like 2 days already. I'm learning a lot on this forum.
  26. #14
  27. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Jun 2012
    Posts
    776
    Rep Power
    495
    Yes, you've got it, this is exactly what I wanted you to arrive at.

    As a matter of personal taste, I would personally write the loop in a slightly simpler syntactic form:

    Perl Code:
    for my $count (0..$arraysize1 - 1) {
    	return 0 if @$arrayref[$count] !=  @$arrayref2[$count];
    }
    return 1;
  28. #15
  29. No Profile Picture
    PerlGuy
    Devshed Novice (500 - 999 posts)

    Join Date
    Jan 2001
    Posts
    720
    Rep Power
    42
    Originally Posted by seedofwinter
    But why wasn't the other one working? It will bother me all day. Even if I adjust the count it wouldn't work.
    I think you're asking why your second attempt wasn't working? If so, I think it's this bit:
    Code:
                             foreach my $i(@$arrayref2){
                                if($j == $i){
                                    if($count < $arraysize1) { next; }
                                    else { 
                                    	return 1; 
                                    }
                                }
                                else { return 0; }
                              }
    You should be able to step through it mentally to really see what's happening, and practicing that ought to help you debug your own code in the future.

    starting with the beginning if the inner foreach loop.
    1. set $i = 1 ($j is already set to 1 at this point)
    2. evaluate $i == $j, which is true so enter that block
    3. evaluate $count < $arraysize1, which is true, so enter that block.
    4. next, go to the next pass through the inner foreach loop
    5. (back at start of inner foreach loop) set $i = 2
    6. evaluate $i = $j, which is false ($j still set to 1), so go to the false block, which returns 0.
    - dsb -
    Perl Guy
Page 1 of 2 12 Last
  • Jump to page:

IMN logo majestic logo threadwatch logo seochat tools logo