Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Page 1 of 2 12 LastLast
Results 1 to 15 of 16
  1. #1
    Regular Coder
    Join Date
    Nov 2007
    Posts
    680
    Thanks
    319
    Thanked 1 Time in 1 Post

    array_diff only compare array element ONCE

    I'm having a problem here, as I only want the $chars to compare each array element ONCE, and if a match is found then it should be removed...

    Because as you can see, both words here will be added to the $con_words array, as the function is using the "e" twice.

    PHP Code:
    <?php
    $words 
    = array("mobile""belief");
    $chars = array("m","o","b","i","l","e","h","u","f","h","n","k");

    for (
    $i 0$i count($words); $i++) {
        
    $word_spl str_split($words[$i]);
        
    $result array_diff($word_spl$chars);
        if (empty(
    $diff))    {
            
    $con_words[] = $words[$i];
        }
    }

    print_r($con_words);
    ?>

  • #2
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,978
    Thanks
    4
    Thanked 2,659 Times in 2,628 Posts
    Pull the array_diff the other way as well:
    PHP Code:
    $diff array_diff($word_spl$chars);
    $chars array_diff($chars$word_spl); 
    I assumed that $result should have been $diff. This will remove any repetition as well though.

  • Users who have thanked Fou-Lu for this post:

    martynball (04-26-2012)

  • #3
    Regular Coder
    Join Date
    Nov 2007
    Posts
    680
    Thanks
    319
    Thanked 1 Time in 1 Post
    How do I go about checking?

    PHP Code:
    <?php
    $words 
    = array("mobile""belief");
    $chars = array("m","o","b","i","l","e","h","u","f","h","n","k");

    for (
    $i 0$i count($words); $i++) {
        
    $word_spl str_split($words[$i]);
        
        
    $diff array_diff($word_spl$chars);
        
    $chars array_diff($chars$word_spl);
        
        if (empty(
    $chars) && empty($diff))    {
            
    $con_words[] = $words[$i];
        }
    }

    print_r($con_words);
    ?>
    I'm guessing like above, then then no words are displayed. But if I just do this:
    PHP Code:
    if (empty($diff))    {
            
    $con_words[] = $words[$i]; 
    Then ONLY "mobile" is displayed, but that just ignores the second check? :S

  • #4
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,978
    Thanks
    4
    Thanked 2,659 Times in 2,628 Posts
    The condition doesn't change. The $chars has been reassigned to remove the characters used in the first array_diff call.

  • Users who have thanked Fou-Lu for this post:

    martynball (04-26-2012)

  • #5
    Regular Coder
    Join Date
    Nov 2007
    Posts
    680
    Thanks
    319
    Thanked 1 Time in 1 Post
    Ah I see, thanks

  • #6
    Regular Coder
    Join Date
    Nov 2007
    Posts
    680
    Thanks
    319
    Thanked 1 Time in 1 Post
    Actually, it still doesn't seem to work when looking through a dictionary.

    If I enter these characters:
    Code:
    b,a,t,t,e,r,y,g,j,u,b,t
    No word is actually found, the word that should be found is "battery". It is in the database:
    Code:
      ID     word
    6909	battery
    If I just stick with the code below, it finds "battery" but also another 42 words as well. Which should not happen. If I add that extra bit of code:
    PHP Code:
    $chars array_diff($chars$word_split); 
    Then no words are found at all.

    PHP Code:
    //Add all characters to Array
    while ($g != 13) {
        
    $c_char mysql_real_escape_string($_GET['char'.$g]); //Current character
        
    if ($c_char) {
            
    $chars[] = $c_char;
        }
        
    $g++;
    }

    //Start fecthing database data
    $query "SELECT * FROM dictionary WHERE LENGTH(word) = ".$length." ORDER BY ranking DESC";
    $result mysql_query($query);

    if(!
    $result) { $return_data "Error connecting to dictionary!"; }

    //Fetch word matching the selected length
    while($row mysql_fetch_array($result)) 

        
    $data trim($row['word']);
        
    $word_split str_split($data); 
        
        
    $diff array_diff($word_split$chars); 
        
    //$chars = array_diff($chars, $word_split);
        
        
    if (empty($diff))    {
            
    $con_words[] = $data;
        }

    Any ideas? As I have not got a clue.

  • #7
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,978
    Thanks
    4
    Thanked 2,659 Times in 2,628 Posts
    Now you just have me confused. If I do this:
    PHP Code:
    $aChars = array('b','a','t','t','e','r','y','g','j','u','b','t');
    $string "battery";

    $aString str_split($string);
    $diff array_diff($aString$aChars);
    $aChars array_diff($aChars$aString);
    if (empty(
    $diff))
    {
        
    printf("Characters found in %s" PHP_EOL$string);
    }
    print_r($aChars); 
    Will result in:
    Code:
    Characters found in battery
    Array ( [7] => g [8] => j [9] => u )
    As I said it will consume all the characters within the strings when calculating the difference. The only remaining characters are g, j and u, and that doesn't really form any possible words. Therefore a call to the empty($diff) will result in a lot of falses to follow unless your word is gju, guj, jgu, jug, ugj, or ujg.

    So what exactly is it you are trying to do here? It almost looks like a spell checker. If this is the case you may be better off using a levenshtein and metaphone to find similar words. Both of these can be used when inserting data into the database to create two additional columns to search on, then calculate the word input and select from the database where they match. If the levenshtein and metaphone both match in a single row, that should be the literal input, while you can sort the results remaining by either spells with the same characters (levenshtein) or sounds the same (metaphone).

  • #8
    Regular Coder
    Join Date
    Nov 2007
    Posts
    680
    Thanks
    319
    Thanked 1 Time in 1 Post
    Basically, what it should do is search for words which can be made with the given characters, and are a defined length. So far it work's but it's finding too many words as it is using some characters more than once.

    Once a character has been used it shouldn't be used again.

  • #9
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,978
    Thanks
    4
    Thanked 2,659 Times in 2,628 Posts
    Okay, then if I got you right you just want to make sure you have enough characters to spell the word?
    PHP Code:
    <?php

    function canSpellsWord($sWord, array $aFromChars)
    {
        
    $bResult true;
        
    $aWord count_chars($sWord1);
        
    $aLetters array_count_values($aFromChars);

        
    $iLetters count($aWord);
        if (
    count($aFromChars) > 0)
        {
            while (
    $bResult && (list($key$val) = each($aWord)))
            {
                
    $c chr($key);
                if (!isset(
    $aLetters[$c]) || $aLetters[$c] < $val)
                {
                    
    $bResult false;
                }    
            }
        }
        else
        {    
            
    $bResult false;
        }

        return 
    $bResult;
    }

    $words = array("mobile""belief""funkei");
    $chars = array("m","o","b","i","l","e","h","u","f","h","n","k");

    foreach (
    $words AS $word)
    {
        
    printf('$chars can spell word %s? %d' PHP_EOL$wordcanSpellsWord($word$chars));
    }

  • Users who have thanked Fou-Lu for this post:

    martynball (04-27-2012)

  • #10
    Regular Coder
    Join Date
    Nov 2007
    Posts
    680
    Thanks
    319
    Thanked 1 Time in 1 Post
    After reading through that code and researching many functions that I have not come across I think that will solve my problem.

    I will have another read through tomorrow and try and implant it into my code to see if it does what I want. I don't like using someone elses code until I understand exactly what it does.

    I don't see the point in coding something if it's all copy and paste, don't learn anything like that. So before I will use this I need to fully understand it.

  • #11
    Regular Coder
    Join Date
    Nov 2007
    Posts
    680
    Thanks
    319
    Thanked 1 Time in 1 Post
    That function will make sure that each char item is only used ONCE, correct?

  • #12
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,978
    Thanks
    4
    Thanked 2,659 Times in 2,628 Posts
    Quote Originally Posted by martynball View Post
    That function will make sure that each char item is only used ONCE, correct?
    Correct, but for each word.

  • Users who have thanked Fou-Lu for this post:

    martynball (04-27-2012)

  • #13
    Regular Coder
    Join Date
    Nov 2007
    Posts
    680
    Thanks
    319
    Thanked 1 Time in 1 Post
    Quick question, this line here function canSpellsWord($sWord, array $aFromChars) , do you need to put "array" in front of the, well array so that it stays an array whilst being passed to the function?

  • #14
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,978
    Thanks
    4
    Thanked 2,659 Times in 2,628 Posts
    No, that only forces it to only accept an array. I wish PHP at least type hint strong for all primitive datatypes, but only array and a class type can be used for the datatype in the signature.

  • Users who have thanked Fou-Lu for this post:

    martynball (04-27-2012)

  • #15
    Regular Coder
    Join Date
    Nov 2007
    Posts
    680
    Thanks
    319
    Thanked 1 Time in 1 Post
    Hmm, strange.

    This should work, but instead blank values are displayed... Roughly about 4000

    PHP Code:
    //Start fecthing database data
    $query "SELECT * FROM dictionary WHERE LENGTH(word) = ".$length." ORDER BY ranking DESC";
    $result mysql_query($query);

    if(!
    $result) { $return_data "Error connecting to dictionary!"; }

    //Fetch word matching the selected length
    while($row mysql_fetch_array($result)) 

        
    $data trim($row['word']);
        
        
    $con_words[] = canSpellsWord($data$chars);



  •  
    Page 1 of 2 12 LastLast

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •