PHP: Extract word from string and get word count - php

I have tried for hours to figure this out, to no avail. I have searched and searched, with a lot of results saying to use an array. I can not use an array as this has not been covered in my class yet. Here is what I am to do:
I am to use a for loop to examine the characters using index variable.
When a blank character is found, this indicated the end of the word.
I then need to extract the word from the string and increment the word count, thus printing the word count and extracted word, continuing til the end of the sentence.
Then printing the total word count.
What I am stuck on is extracting the word. Here is what I have so far, which could very well be wrong but I am at my wits end here, so any little bit of push in the right direction would be great.
(Remember, I can not use arrays.)
$stringSentence = "The quick brown fox jumps over the lazy dog";
$wordcount = 1;
$blankCharacter = stripos($stringSentence, " ");
for ($i =0; $i<strlen($stringSentence);$i++)
{
$i. " ". $stringSentence{$i}."<br>";
}
if ($blankCharacter)
{
echo $wordcount++, " ";
echo substr($stringSentence,0,$blankCharacter);
}
Thanks for any help.

Have you considered just going through each individual letter to check for spaces and storing in a temporary buffer otherwise? One example:
$stringSentence = "The quick brown fox jumps over the lazy dog";
$buffer = '';
$count = 1;
$length = strlen($stringSentence);
for ($i = 0; $i < $length; $i++) {
if ($stringSentence{$i} !== ' ') {
$buffer .= $stringSentence{$i};
} else {
echo $count++ . ' ' . $buffer . ' ';
$buffer = '';
}
}
echo $count . ' ' . $buffer;
I'm not putting much explanation into my answer.. sort of a backwards approach of giving you the answer but it's up to you to understand how and why the above approach works.

Since this is home work I can't do it for you but you have an end bracket for one in the wrong place
Have a look at this sudo code and you should be in the right direction.
$blankCharacter = ' ';
for ($i =0; $i<strlen($stringSentence);$i++)
{
if (thisCharacter == $blankCharacter)
{
$wordcount++;
}
}

Arrays aren't that complicated! And a solution is very easy with it:
(Here I just explode() your string into an array. Then I simply loop through the array and print the output)
<?php
$stringSentence = "The quick brown fox jumps over the lazy dog";
$words = explode(" ", $stringSentence);
foreach($words as $k => $v)
echo "WordCount: " . ($k+1) . "| Word: $v<br>";
echo "Total WordCount: " . count($words);
?>
output:
WordCount: 1| Word: The
//...
WordCount: 9| Word: dog
Total WordCount: 9
If you want to read more about arrays see the manual: http://php.net/manual/en/language.types.array.php
EDIT:
If you can't use arrays, just use this:
Here I just loop through all characters of the sentence to check if it is either a space OR the end of the string. If the condition is true I print the word count + the substr from the last space until the current one. Then I also increment the word count with 1. At the end I simply print the total word count (note that I subtracted 1, because the last word will also add 1 to the count which is too much).
<?php
$stringSentence = "The quick brown fox jumps over the lazy dog";
$wordcount = 1;
$blankCharacter = 0;
for ($i = 0; $i < strlen($stringSentence); $i++) {
if($stringSentence[$i] == " " || $i+1 == strlen($stringSentence)) {
echo "WordCount: $wordcount | Word: " . substr($stringSentence, $blankCharacter, $i-$blankCharacter+1) . "<br>";
$blankCharacter = $i;
$wordcount++;
}
}
echo "Total WordCount: " . ($wordcount-1);
?>

Related

PHP split string to next period (.)

My aim is to split string after every 7 words. If the 7th word has a comma (,), move to the next word with period (.) or exclamation (!)
So far, I've been able to split string by 7 words, but cannot check if it contains commas (,) or move to the next word with . or !
$string = "I have a feeling about the rain, let us ride. He figured I was only joking.";
$explode = explode(" ", $string);
$chunk_str = array_chunk($explode, 7);
for ($x=0; $x<count($chunk_str); $x++)
{
$strip = implode(" ",$chunk_str[$x]);
echo $strip.'<br><br>';
}
I expect
I have a feeling about the rain, let us ride.
He figured I was only joking.
But the actual output is
I have a feeling about the rain,
let us ride. He figured I was
only joking.
Here's one way to do what you want. Iterate through the list of words, 7 at a time. If the 7th word ends with a comma, increase the list pointer until you reach a word ending with a period or exclamation mark (or the end of the string). Output the current chunk. When you reach the end of the string, output any remaining words.
$string = "I have a feeling about the rain, let us ride. He figured I was only joking.";
$explode = explode(' ', $string);
$num_words = count($explode);
if ($num_words < 7) {
echo $string;
}
else {
$k = 0;
for ($i = 6; $i < count($explode); $i += 7) {
if (substr($explode[$i], -1) == ',') {
while ($i < $num_words && substr($explode[$i], -1) != '.' && substr($explode[$i], -1) != '!') $i++;
}
echo implode(' ', array_slice($explode, $k, $i - $k + 1)) . PHP_EOL;
$k = $i + 1;
}
}
echo implode(' ', array_slice($explode, $k)) . PHP_EOL;
Output:
I have a feeling about the rain, let us ride.
He figured I was only joking.
Demo on 3v4l.org

Auto switch between sentences

I would like my joomla site to automatically change which sentence it will echo to the user, so I wrote 3 different sentences:
$sentence1 = "Everything okay?";
$sentence2 = "Have a good day";
$sentence3 = "What are you doing today?";
I would like it to switch between the sentences, so I'm aware I can't just put $sentence1 in the echo but I don't know how to write it then. I have the echo line like this:
echo "Hey {user->name}." . "<br />" . $sentence1
By the way, the {user->name} is from Joomla's own "codes" so that worked fine :)
random greetings:
$sentence[1] = "Everything okay?";
$sentence[2] = "Have a good day";
$sentence[3] = "What are you doing today?";
echo "Hey {user->name}." . "<br />" . $sentence[rand(1,3)]
You could use a random function, such as mt_rand():
$sentence1 = "Everything okay?";
$sentence2 = "Have a good day";
$sentence3 = "What are you doing today?";
$nb = mt_rand(1, 3); // Gets a random number from 1 to 3
$sentence_shown = ${'sentence' . $nb}; // Equals $sentence1, $sentence2 or $sentence3
echo "Hey {user->name}." . "<br />" . $sentence_shown;
Or even better, put your three strings in an array :
$sentences = array();
$sentences[] = "Everything okay?";
$sentences[] = "Have a good day";
$sentences[] = "What are you doing today?";
$nb = mt_rand(0, 2); // Gets a random number from 0 to 2
$sentence_shown = $sentences[$nb];
echo "Hey {user->name}." . "<br />" . $sentence_shown;
In my opinion, you can put your 3 sentences or 3 strings in an array, and then you can print every sentence when you loop in it. Example:
$array = array(sentence1, sentence2, sentence3 , ... , sentence n);
for ($index = 0; $index < sizeof($array); $index++) {
echo 'This is sentence ' + index ':' + $array[index];
}

Extract and merge strings between different positions

I'm trying to make this works. I want to replace some parts of a sentence between given positions and then show the full sentence with the changes. With the following code, I'm able to make the changes but I don't know how to put together the rest of the sentence.
I have two arrays, one with the positions where a woman name appears and another one with men names. The code replaces the pronoun "his" by "her" when a woman is before a man between the intervals. The last thing I need is to reconstruct the sentence with the changes made but I don't know how to extract the rest of the sentence (the result, in the example, is from positions 0 to 20 (Maria her dress but) and 36 to 51 (Lorena her dog) but I need to extract from 20 to 36 (Peter his jeans) and 51 to the end (Juan his car) to merge them in their positions).
The result should be: "Maria her dress but Peter his jeans Lorena her dog Juan his car". I'll appreciate any help with this, I've been looking for other similar questions but I found nothing.
<?php
$womenpos = array("0","36"); //these arrays are just examples of positions
$menpos = array("20","51"); //they will change depending on the sentence
$sentence = "Maria his dress but Peter his jeans Lorena his dog Juan his car";
echo $sentence."\n";
foreach ($womenpos as $index => $value) {
$value2 = $menpos[$index];
if($value < $value2) {
echo "\nWoman(" . $value . ") is before man(" . $value2 . ")\n";
$end = ($value2 - $value);
$improved = str_replace(' his ', ' her ',
substr($sentence, $value, $end));
echo $improved."\n";
} else {
$improved = "Nothing changed";
echo $improved;
}
}
Ok, how about this:
$womenpos = array("0","36");
$menpos = array("20","51");
$bothpos = array_merge($womenpos,$menpos);
sort ($bothpos);
print_r($bothpos);
$sentence = "Maria his dress but Peter his jeans Lorena his dog Juan his car";
echo $sentence."\n";
for ($i = 0; $i<sizeof($bothpos); $i++) {
$start = $bothpos[$i];
if ($i ==sizeof($bothpos)-1) {
$end = strlen($sentence);
}
else {
$end = $bothpos[$i+1];
}
$length = $end-$start;
$segment = substr($sentence, $start, $length);
if (in_array($start, $womenpos)) {
$new_segment = str_replace (' his ', ' her ', $segment);
}
else { $new_segment = $segment; }
$improved .= $new_segment;
print "<li>$start-$end: $segment : $new_segment </li>\n";
}
print "<p>Improved: $improved</p>";
This combines the men's and women's position arrays to consider each stretch of text as one that might have an error. If that stretch of text starts at one of the womenpos points, then it changes 'his' to 'her'. If not it leaves it alone.
Does this get you in the direction you want to go in? I hope so!
This approaches the problem differently, but I wonder if it would provide the solution you're looking for:
$sentence = "Maria his dress but Peter his jeans Lorena his dog Juan his car";
$women = array ("Maria", "Lorena");
$words = explode (" ", $sentence);
for ($i=0; $i< sizeof($words); $i++) {
if ($words[$i] == "his" && in_array($words[$i-1], $women)) {
$words[$i] = "her";
}
}
print (join(" ", $words));
This goes through the words one at a time; if the preceding word is in the $women array and the current word is "his", it changes the word to "her". Then it spits out all the words in order.
Does this do what you need, or do you really want a complex string positioning answer?

PHP Word guessing game (highlight letters in right and wrong position - like mastermind)

Sorry for the long title.
Wanted it to be as descriptive as possible.
Disclaimer : Could find some "find the differences" code here and elsewhere on Stackoverflow, but not quite the functionality I was looking for.
I'll be using these terminoligy later on:
'userguess' : a word that will be entered by the user
'solution' : the secret word that needs to be guessed.
What I need to create
A word guessing game where:
The user enters a word (I'll make sure through Javascript/jQuery that
the entered word contains the same number of letters as the word to
be guessed).
A PHP function then checks the 'userguess' and highlights (in green)
the letters in that word which are in the correct place, and
highlights (in red) the letters that are not yet in the right place,
but do show up somewhere else in the word. The letters that don't
show up in the 'solution' are left black.
Pitfall Scenario : - Let's say the 'solution' is 'aabbc' and the user guesses 'abaac'
In the above scenario this would result in : (green)a(/green)(red)b(/red)(red)a(/red)(black)a(/black)(green)c(/green)
Notice how the last "a" is black cause 'userguess' has 3 a's but 'solution' only has 2
What I have so far
Code is working more or less, but I've got a feeling it can be 10 times more lean and mean.
I'm filling up 2 new Arrays (one for solution and one for userguess) as I go along to prevent the pitfall (see above) from messing things up.
function checkWord($toCheck) {
global $solution; // $solution word is defined outside the scope of this function
$goodpos = array(); // array that saves the indexes of all the right letters in the RIGHT position
$badpos = array(); // array that saves the indexes of all the right letters in the WRONG position
$newToCheck = array(); // array that changes overtime to help us with the Pitfall (see above)
$newSolution = array();// array that changes overtime to help us with the Pitfall (see above)
// check for all the right letters in the RIGHT position in entire string first
for ($i = 0, $j = strlen($toCheck); $i < $j; $i++) {
if ($toCheck[$i] == $solution[$i]) {
$goodpos[] = $i;
$newSolution[$i] = "*"; // RIGHT letters in RIGHT position are 'deleted' from solution
} else {
$newToCheck[] = $toCheck[$i];
$newSolution[$i] = $solution[$i];
}
}
// go over the NEW word to check for letters that are not in the right position but show up elsewhere in the word
for ($i = 0, $j = count($newSolution); $i <= $j; $i++) {
if (!(in_array($newToCheck[$i], $newSolution))) {
$badpos[] = $i;
$newSolution[$i] = "*";
}
}
// use the two helper arrays above 'goodpos' and 'badpos' to color the characters
for ($i = 0, $j = strlen($toCheck), $k = 0; $i < $j; $i++) {
if (in_array($i,$goodpos)) {
$colored .= "<span class='green'>";
$colored .= $toCheck[$i];
$colored .= "</span>";
} else if (in_array($i,$badpos)) {
$colored .= "<span class='red'>";
$colored .= $toCheck[$i];
$colored .= "</span>";
} else {
$colored .= $toCheck[$i];
}
}
// output to user
$output = '<div id="feedbackHash">';
$output .= '<h2>Solution was : ' . $solution . '</h2>';
$output .= '<h2>Color corrected: ' . $colored . '</h2>';
$output .= 'Correct letters in the right position : ' . count($goodpos) . '<br>';
$output .= 'Correct letters in the wrong position : ' . count($badpos) . '<br>';
$output .= '</div>';
return $output;
} // checkWord
Nice question. I'd probably do it slightly differently to you :) (I guess that's what you were hoping for!)
You can find my complete solution function here http://ideone.com/8ojAG - but I'm going to break it down step by step too.
Firstly, please try and avoid using global. There's no reason why you can't define your function as:
function checkWord($toCheck, $solution) {
You can pass the solution in and avoid potential nasties later on.
I'd start by splitting both the user guess, and the solution into arrays, and have another array to store my output in.
$toCheck = str_split($toCheck, 1);
$solution = str_split($solution, 1);
$out = array();
At each stage of the process, I'd remove the characters that have been identified as correct or incorrect from the users guess or the solution, so I don't need to flag them in any way, and the remaining stages of the function run more efficiently.
So to check for matches.
foreach ($toCheck as $pos => $char) {
if ($char == $solution[$pos]) {
$out[$pos] = "<span class=\"green\">$char</span>";
unset($toCheck[$pos], $solution[$pos]);
}
}
So for your example guess/solution, $out now contains a green 'a' at position 0, and a green c at position 4. Both the guess and the solution no longer have these indices, and will not be checked again.
A similar process for checking letters that are present, but in the wrong place.
foreach ($toCheck as $pos => $char) {
if (false !== $solPos = array_search($char, $solution)) {
$out[$pos] = "<span class=\"red\">$char</span>";
unset($toCheck[$pos], $solution[$solPos]);
}
}
In this case we are searching for the guessed letter in the solution, and removing it if it is found. We don't need to count the number of occurrences because the letters are removed as we go.
Finally the only letters remaining in the users guess, are ones that are not present at all in the solution, and since we maintained the numbered indices throughout, we can simply merge the leftover letters back in.
$out += $toCheck;
Almost there. $out has everything we need, but it's not in the correct order. Even though the indices are numeric, they are not ordered. We finish up with:
ksort($out);
return implode($out);
The result from this is:
"<span class="green">a</span><span class="red">b</span><span class="red">a</span>a<span class="green">c</span>"
Here try this, See In Action
Example output:
<?php
echo checkWord('aabbc','abaac').PHP_EOL;
echo checkWord('funday','sunday').PHP_EOL;
echo checkWord('flipper','ripple').PHP_EOL;
echo checkWord('monkey','kenney').PHP_EOL;
function checkWord($guess, $solution){
$arr1 = str_split($solution);
$arr2 = str_split($guess);
$arr1_c = array_count_values($arr1);
$arr2_c = array_count_values($arr2);
$out = '';
foreach($arr2 as $key=>$value){
$arr1_c[$value]=(isset($arr1_c[$value])?$arr1_c[$value]-1:0);
$arr2_c[$value]=(isset($arr2_c[$value])?$arr2_c[$value]-1:0);
if(isset($arr2[$key]) && isset($arr1[$key]) && $arr1[$key] == $arr2[$key]){
$out .='<span style="color:green;">'.$arr2[$key].'</span>';
}elseif(in_array($value,$arr1) && $arr2_c[$value] >= 0 && $arr1_c[$value] >= 0){
$out .='<span style="color:red;">'.$arr2[$key].'</span>';
}else{
$out .='<span style="color:black;">'.$arr2[$key].'</span>';
}
}
return $out;
}
?>

issue in printing dimension of numbers php

I am just a beginner in PHP. I am trying to write program to print numbers like following.
1 1
12 21
123 321
1234 4321
1234554321
I have written the following code.
<?php
$n=5;
for($i=1; $i<=$n; $i++)
{
echo "<br />";
for($j=1; $j<=$i; $j++)
{
echo $j;
}
}
?>
The result displays the following.
1
12
123
1234
12345
I could not reverse it like
1
21
321
4321
54321
How can I do this?
The simplest, hard coded version:
<?php
$text = "1 1
12 21
123 321
1234 4321
1234554321";
echo $text;
?>
Edit
A more generic solution:
<?php
$n = 5;
$seq1 = '';
$seq2 = '';
$format1 = sprintf("%%-%su", $n); //right justified with spaces
$format2 = sprintf("%%%su", $n); //left justified with spaces
for($i=1; $i<=$n;$i++){
$seq1 .= $i;
$seq2 = strrev($seq1);
echo sprintf("$format1$format2\n", $seq1, $seq2);
};
?>
Okay. What you wrote is pretty good. There need to be several changes in order to do what you wanted though. The first problem is that you are rendering it to HTML - and HTML does not render spaces (which we'll need). Two solutions: you use for space, and make sure you use a proportional font, or you wrap everything into a <pre> tag to achieve pretty much the same thing. So, echo "<pre>"; at the start, echo "</pre>"; at the end.
Next - don't have the inner loop go to $i. Let it go to 5 every time, and print a number if $j <= $i, and a space otherwise.
Then, right next to this loop, do another one, but in reverse (starting with 5 and ending with 1), but doing the very same thing.
Viola is a musical instrument.
Here is my solution to your problem.
It isn't the best solution because it doesn't take into account that you could be using numbers higher than 9, in which case it will push the numbers out of line with each other.
But the point is that it is still the start of a solution that you could work on if needed.
You can use an array to store the numbers you want to print.
Because the numbers are in an array it means we can just use a foreach loop to make sure all of the numbers get printed.
You can use PHP's str_repeat() function to figure out how many spaces you need to put in between each string of numbers.
The below solution will only work if you use an array with the default number indicies as opposed to an associative array.
This is because it uses the $key variable in part of the calculation for the str_repeat() function.
If you would rather not use the $key variable then you should be able to figure out how to change that.
When it come to reversing the numbers they have already been stored in a string so you can just use PHP's strrev() function to take care of that and store them in another variable.
Finally you just have to print a line to the document with a line break at the end.
Note that the str_repeat() function is repeating the HTML entity.
This is because the browser will just compress normal white space down to 1 character.
Also note that I have included a style block to change the font to monospace.
This is to ensure that the numbers all line up with each other.
<style>
html, body {
font: 1em monospace;
}
</style>
<?php
$numbers = array(1, 2, 3, 4, 5);
$numbers_length = count($numbers);
$print_numbers = '';
$print_numbers_rev = '';
foreach($numbers as $key => $value) {
$spaces = str_repeat(' ', ($numbers_length - ($key + 1)) * 2);
$print_numbers .= $value;
$print_numbers_rev = strrev($print_numbers);
echo $print_numbers . $spaces . $print_numbers_rev . '<br />';
}
Edit:
Solution without array:
<style>
html, body {
font: 1em monospace;
}
</style>
<?php
$numbers = 9;
$numbers_length = $numbers + 1;
$print_numbers = '';
$print_numbers_rev = '';
for($i = 0; $i <= $numbers; ++$i) {
$spaces = str_repeat(' ', ($numbers_length - ($i + 1)) * 2);
$print_numbers .= $i;
$print_numbers_rev = strrev($print_numbers);
echo $print_numbers . $spaces . $print_numbers_rev . '<br />';
}
$n = 5;
for ($i = 1; $i <= $n; $i++) {
$counter .= $i;
$spaces = str_repeat(" ", ($n-$i)*2);
echo $counter . $spaces . strrev($counter) . "<br/>";
}
<div style="position:relative;width:100px;height:auto;text-align:right;float:left;">
<?php
$n=5;
for($i=1; $i<=$n; $i++)
{
echo "<br />";
for($j=1; $j<=$i; $j++)
{
echo $j;
}
}
?>
</div>

Categories