0

I want to get the count of characters from the following words in the string. For example, if my input is I am John then the output must be like this:

1 // count of 'I'
4 // count of 'I am'
9 // count of 'I am John'

I use the code like this in PHP for this process:

$string = 'I am John';
$words = explode(' ',$string);
$count_words = count($words);

$i =0;
while ($i<=$count_words){
    $word_length =0;
    $k=0;
    while($k<=$i){
        $word_length = strlen($words[$k-1]);
        $word_length = $word_length + strlen($words[$k]);
        $k++;
    }
    $word_length = $word_length + $i; // there is "$i" means "space"
    echo $word_length.'<br/>';
    $i++;

}

But it return the output like this:

1
4
8
7

Why ? Where is my error ? What does my code must be like ?
Thanks in advance!

3
  • 2
    Re title: No, you have not just found a bug in one of the most basic, widely used language constructs of one of the most popular languages in use to date. :o) Commented Jan 21, 2012 at 9:13
  • ok :) what title do you suggest ? :) Commented Jan 21, 2012 at 9:15
  • 2
    Here's a freebie: codepad.viper-7.com/3R02TK But seriously, learn to debug your own code, else you won't get anything done in programming. Debugging just means to go through the code step by step to figure out what's wrong. Use var_dump() a lot. Commented Jan 21, 2012 at 9:28

4 Answers 4

1
<?php
$string = 'I am John';
$words = explode(' ',$string);
$count_words = count($words);
$i =0;
while ($i<$count_words){
    if($i==0) {
    $wordsc[$i] = strlen($words[$i]);
    } else {
    $wordsc[$i] = strlen($words[$i])+1+$wordsc[$i-1];
    }
    echo $wordsc[$i]."<br>";
    $i++;
}
?>
Sign up to request clarification or add additional context in comments.

Comments

1

Your error is here:

$i =0;
while ($i<=$count_words){
   //....
}

$count_words is 3, but you iterate 4 times because of <=. Use < instead.

5 Comments

ok, thanks. but now it returns 1 4 8 . why '8' in the end ? but there must be '9' instead of '8'.
@John there are more problems with the code - $words[$k-1] at the first iteration will be $words[-1] for one. I tested the code and it doesn't print what you said it does.
so, what do you suggest ? what do I must use istead of $words[$k-1] ?
@John I suggest you re-think your algorithm. We can help with specific issues, not re-write your code for you so that it works. Have you even tried debugging?
No, I haven't ( Actually, I don't know how to debug PHP script. Now I'm looking for it. Do you think debugging will be helpful for me ?
1
  1. You were looping through to many words. When you use count it returns the number of elements in an array. Remember an array starts at 0.
  2. $word_length + strlen($words[$k - 1]); // You were subtracting 1 I think you were trying to cater for the count offest but you are subtracting -1 from 0 causing the first word to be missed.

CODE SNIPPET START

//Set up the words

$string = 'I am John';

$words = explode(' ',$string);

$count_words = count($words);

//Loop through the words
$i =0;

while ($i<$count_words){

$word_length =0;
$k=0;

$debugString = '';

//Loop through all the previous words to the current
while($k<= $i){

    //dont really need this since were adding the word length later
    //$word_length = strlen($words[$k]);

    //if you -1 from 0 you will get an undefined offest notice. You
    //want to look at your current word
    $word_length = $word_length + strlen($words[$k]);

    //A bit of debugging you can delete this once you have seen the results
    $debugString = $debugString ." ".$words[$k];

    $k++;
}

$word_length = $word_length + $i ; // there is "$i" means "space"

//Added the debugString for debugging so remove it once you have seen the results
echo $word_length." " .$debugString.' <br/>';
$i++;

}

CODE SNIPPET END

Comments

0

I am happy to provide you with a completely different approach for generating your desired data in a very direct way. (Demo of what is to follow)

var_export(preg_match_all('/ |$/','I am John',$out,PREG_OFFSET_CAPTURE)?array_column($out[0],1):'failure');

Output:

array (
  0 => 1,
  1 => 4,
  2 => 9,
)

Determining the length of each word-incremented substring is effectively the same as determining the offset of each trailing space, or on the final word - the full string length.

preg_match_all() has a built-in "flag" for this: PREG_OFFSET_CAPTURE

preg_match_all() before any array manipulation will output this:

array (
  0 => 
  array (
    0 => 
    array (
      0 => ' ',   // <-- the space after 'I' matched by ' '
      1 => 1,
    ),
    1 => 
    array (
      0 => ' ',  // <-- the space after 'am' matched by ' '
      1 => 4,
    ),
    2 => 
    array (
      0 => '',  // <-- the end of the string (after 'John') matched by '$'
      1 => 9,
    ),
  ),
)

array_column() is used on the $out[0] to extract only the offset values (omitting the useless blank and empty strings).


Here is another, totally different method:

array_reduce(preg_split('/(?= )/',$string),function($carry,$item){echo $carry+=strlen($item)," "; return $carry;},0);
output: 1 4 9 

This splits the string on the "zero-width" string that is followed by a space. This means that in the exploding process, the spaces are not lost -- this maintains the string and substring lengths for simple addition.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.