I have
$char=array("1","2","3","4","5","6","7","8","9","0","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","-");
$doma=array("aero","asia","biz","cat","com","coop","info","int","jobs","mobi","museum","name","net","org","pro","tel","travel","xxx","edu","gov","mil","co.uk","co.nr","co.au","au","ca","co.cc","cc","co","cn","co.jp","de","es","ie","in","it","jp","nl","nz","ru","co.tk","tk","tv","us")
and what I would like to do, is:
from a length of 1 up to a length of 32 arrange the chars into a string, echoing the string, then going back to the beginning again. So eventually my browser would look something like this:
0.aero
1.aero
2.aero
3.aero
....
x.aero
y.aero
z.aero
-.aero
00.aero
01.aero
02.aero
....
za.aero
zb.aero
zc.aero
zd.aero
....
50x90zx908.aero
50x90zx909.aero
50x90zx90a.aero
50x90zx90b.aero
....
50x90zx910.aero
50x90zx911.aero
ect; ect;
How would I create for loops to do this? to include the $doma ones to the end as well each loop?
I know this is huge, but when I've got an idea I gotta try it ;)
If you really want to do this with for loops, then make 33 of them, one for each desired length (1-32) and one for the $doma array.
But I would not do it that way. Instead, observe that the desired combinations of the characters in the $char array actually form a tree. The root node represents the empty string. Each child node of the root represents a 1-character combination ("1", "2", "3", ...). Each child node of those nodes represent a 2-character combination that has the prefix of its parent node (so the children of the "1" node would all start with "1"), and so on. The leaves of the tree would be all 32-character combinations of the characters in $char. If there were only three characters, a, b, and c, it would look something like this:
You can then make a recursive function that implements a depth-first traversal of such a tree, and instead of generating the tree in memory and then printing it, you can just have the function output the contents of each node as it reaches it. Throw in a parameter that allows you to place a suffix after the node contents, and wrap the function in a loop that iterates through all elements in $doma, and you're done.
function f($array, $limit, $suffix, $prefix = "", $counter = 0)
{
if ($counter > 0) {
print "$prefix.$suffix\n";
}
if ($counter < $limit) {
foreach ($array as $element) {
f($array, $limit, $suffix, $prefix . $element, $counter+1);
}
}
}
$char=array("1","2","3","4","5","6","7","8","9","0","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","-");
$doma=array("aero","asia","biz","cat","com","coop","info","int","jobs","mobi","museum","name","net","org","pro","tel","travel","xxx","edu","gov","mil","co.uk","co.nr","co.au","au","ca","co.cc","cc","co","cn","co.jp","de","es","ie","in","it","jp","nl","nz","ru","co.tk","tk","tv","us");
foreach ($doma as $d) {
f($char, 32, $d);
}
The order will not be exactly as you specified, but this ordering is logically consistent with the order of elements in the arrays and the depth-first traversal order.
The code basically treats the character combination like a base-35 number. It adds one each loop.
<?php
$char=array("1","2","3","4","5","6","7","8","9","0","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","-");
$doma=array("aero","asia","biz","cat","com","coop","info","int","jobs","mobi","museum","name","net","org","pro","tel","travel","xxx","edu","gov","mil","co.uk","co.nr","co.au","au","ca","co.cc","cc","co","cn","co.jp","de","es","ie","in","it","jp","nl","nz","ru","co.tk","tk","tv","us");
$combo = array(0,0,0,0,0,0,0,0,0,0); //this stores the ten "digits" of the characters
$pval = 9; //this is the active "place value", the one that you increment
$list = "";
for($i=0;$i<44;$i++) { //loops through doma
for($j=0;$j<2758547353515625;$j++) { //loops through character combos, that long number is the permutations
for($l=0;$l<10;$l++) { //loop displays combo
$list .= $char[$combo[$l]];
}
$list .= "." . $doma[$i] . "<br/>"; //add combo to list
/*This next part check to see if the active digit is 35. It is is, it sets it
equal to zero and looks to the digit on the left. It repeats this until it
no longer finds a 35. This is like going from 09 to 10 in the decimal system. */
if($combo[$pval] == 35) {
while($combo[$pval] == 35) {
$combo[$pval] = 0;
$pval--;
}
}
$combo[$pval]++; //whatever digit it left on gets incremented.
$pval = 9; //reset, go back to first place value
}
for($l=0;$l<10;$l++) {
$combo[$l] = 0; //reset combo for the next top level domain
}
}
echo $list; //print the compiled list.
?>
Related
I have an array $scripts_stack = []; that holds arrays:
$array_item = array('script' => $file_parts, 'handle' => $file_name, 'src' => $url);
array_push($scripts_stack, $array_item);
<?php
for ($i = 0; $i < sizeof($scripts_stack); $i++) {
$child_array = $scripts_stack[$i];
if (is_array($child_array)) {
// Do things with $child_array,
// then remove the child array from $scripts_stack when done with (BELOW)
unset($scripts_stack[$i]);
}
}
echo "Array Size : " . (sizeof($scripts_stack)); // AT THE END
However, my attemts only remove half the elements. No matter what I try, it's only half the items that get removed. sizeof($scripts_stack) is always half the size of what it was at the start.
I'm expecting that it would be empty // AT THE END
Why is it that I only get half the elements in the array removed?
Thank you all in advance.
As mentioned in other answers, $i increments but the sizeof() the array shrinks. foreach() is probably the most flexible looping for arrays as it exposes the actual key (instead of hoping it starts at 0 and increments by 1) and the value:
foreach ($scripts_stack as $key => $child_array) {
if (is_array($child_array)) {
// Do things with $child_array,
// then remove the child array from $scripts_stack when done with (BELOW)
unset($scripts_stack[$key]);
}
}
Just FYI, the way you're doing it with for almost works. You just need to establish the count before the loop definition, rather than recounting in the continuation condition.
$count = sizeof($scripts_stack);
for ($i = 0; $i < $count; $i++) { // ...
Still, I think it would be better to just use a different type of loop as shown in the other answers. I'd personally go for foreach since it should always iterate every element even if some indexes aren't present. (With the way you're building the array, it looks like the indexes should always be sequential, though.)
Another possibility is to shift elements off of the array rather than explicitly unsetting them.
while ($child_array = array_shift($scripts_stack)) {
// Do things with $child_array,
}
This will definitely remove every element from the array, though. It looks like $child_array should always be an array, so the is_array($child_array) may not be necessary, but if there's more to it that we're not seeing here, and there are some non-array elements that you need to keep, then this won't work.
You advanced $i while the array is getting shrinked, but in the same time you jump over items in your array.
The first loop is where $i == 0, and then when you removed item 0 in your array, the item that was in the second place has moved to the first place, and your $i == (so you will not remove the item in the current first place, and so on.
What you can do is use while instead of for loop:
<?php
$i = 0;
while ($i < sizeof($scripts_stack)) {
$child_array = $scripts_stack[$i];
if (is_array($child_array)) {
// Do things with $child_array,
// then remove the child array from $scripts_stack when done with (BELOW)
unset($scripts_stack[$i]);
} else {
$i++;
}
}
echo "Array Size : " . (sizeof($scripts_stack)); // AT THE END
May be you can use this script.It's not tested.
foreach($array as $key => $value ) {
unset($array[$key]);
echo $value." element is deleted from your array</br>";
}
I hope , it will help you.
The problem root is in comparing $i with sizeof($scripts_stack). Every step further sizeof($scripts_stack) becomes lower (it calculates at every step) and $i becomes higher.
The workaround may look like this:
<?php
$scripts_stack = [];
$array_item = array('script' => 1, 'handle' => 2, 'src' => 3);
array_push($scripts_stack, $array_item);
array_push($scripts_stack, $array_item);
array_push($scripts_stack, $array_item);
array_push($scripts_stack, $array_item);
array_push($scripts_stack, $array_item);
while (sizeof($scripts_stack) > 0) {
$child_array = array_shift($scripts_stack);
if (is_array($child_array)) {
// Do things with $child_array,
// then remove the child array from $scripts_stack when done with (BELOW)
}
}
echo "Array Size : " . (sizeof($scripts_stack)); // AT THE END
https://3v4l.org/N2p3v
i need to make numbers permutations (with some features), but
my .php and mysql is not so improved.
The numbers will be posted by a .html form, max 10 numbers.
It will permute the numbers to create unique thousand number:
if 4 different numbers is posted by the .html input (1,2,3,4):
will return: 1234,1243,1324,1342... (24 unique combinations)
if 5 different numbers is posted by the .html input (1,2,3,4,5):
will return: 1234,1235,1243,... (120 unique combinations)
The number will only repeat if it posted, as (1,1,2,4)
will return: 1124, 1142, 1214,...(12 unique combinations)
Then i need to store the combinations into a mysql row, comma separated.
I tryed this function(found here Permutations - all possible sets of numbers):
$p = permutate(array('1','2','3'));
foreach($p as $perm)
print join("",$perm)."|\n";
function permutate($elements, $perm = array(), &$permArray = array())
{
if(empty($elements))
{
array_push($permArray,$perm); return;
}
for($i=0;$i<=count($elements)-1;$i++)
{
array_push($perm,$elements[$i]);
$tmp = $elements; array_splice($tmp,$i,1);
permutate($tmp,$perm,$permArray);
array_pop($perm);
}
return $permArray;
}
The output: 123| 132| 213| 231| 312| 321|
But when is given:
$p = permutate(array('1','2','2'));
the output is: 122| 122| 212| 221| 212| 221|
When should be 122|212|221
I tried array_unique, but did´t work, probally becouse i did it wrong.
Thx
First convert each result to string and then de-dupe the array:
$p = permutate(array('1','2','3'));
$result = array();
foreach($p as $perm) {
$result[]=join("",$perm);
}
$result = array_unique($result);
print join("|", $result);
I have a small personal project I am trying to complete. I need to take a string of characters and try to "create" words from variations of said string; checking against a text file with a list of known words (words are separated by new lines).
In summary:
user provides string $chars_provided (i.e "jdlwhfushfmgh"),
$chars_provided is then exploded
exploded $chars_provided are randomly arranged in attempt to create words from said string
created words the checked/verified against the dictionary text file to ensure they exist
results are displayed by the character count of the created words, with a limit of 100 words.
I have the concept in my head just not sure how it should be done, I'm just looking for someone who can explain the process to me.
<?php
// list of words, one per line
$dictionary = file_get_contents('dictionary.txt');
// provided characters, in the end by user
$chars_provided = "a,t,w,q,u,i,f,d,s,b,v,x,o";
// count the total # of characters
$chars_count = strlen($chars_provided);
// display given information so far
echo "The letters '$chars_provided' were entered, totaling $chars_count letters.";
// explode the characters by using the comma designator
$break_chars = explode(",", $chars_provided);
foreach ($break_chars as $letter) {
echo "$letter[0]";
}
This is easier if you get the letter counts for each word in the dictionary, hold onto it, and then match against the user input character counts.
For example, with 'aaab', any word with less than (or equal to) 3 'a's, less than (or equal to) 1 'b's, and no other characters will match.
//// 1. Grab letter counts for your user input.
$user_input_chars = 'abcdefg'; // for example
$user_in_letter_counts = get_letter_counts($user_input_chars);
// $letters[$char][$num] will contain all words that have exactly $num number of $char characters
$letters = array('a' => array(), 'b' => array(), /* ...,*/ 'z' => array());
//// 2. Generate list of words with at least $number_of quantity of $letter characters
// (only have to be done once for any amount of user input if you keep this in memory)
foreach ($words as $word){
// get letter counts for each type of character for this word
$letter_counts = get_letter_counts($word);
// store in array of letters and count
foreach($letter_counts as $letter => $number_of){
// we already have a word that had $number_of $letter characters; add word to existing array
if (isset($letters[$letter][$number_of])){
$letters[$letter][$number_of][] = $word;
} // make array to record that this word has $number_of $letter characters
else {
$letters[$letter][$number_of] = array($word);
}
$number_of--;
}
}
//// 3. Find matching words.
$potential_words = array();
foreach ($letters as $letter => $arr){
foreach($arr as $num => $words){
// if this array has less than or equal to the number of $letter characters that the user input has,
// add the words to the potential match list for that character
if ($num <= $arr[$user_in_letter_counts[$letter]]){
$potential_words[$letter] = array_merge($potential_words[$letter], $words);
}
}
}
// the words must have met the requirement for each character, so only grab words that satisfy all conditions
$all_matching_words = array_intersect($potential_words['a'], $potential_words['b'], /* ..., */ $potential_words['z']);
// (It should be trivial to just grab 100 of these.)
function get_letter_counts($word){
$result = array();
$result['a'] = substr_count($my_word, 'a');
$result['b'] = substr_count($my_word, 'b');
// ...
$result['z'] = substr_count($my_word, 'z');
return $result;
}
Hope you can use this.
$file = file_get_contents("dictionary.txt");
$SearchString = "jdlwhfushfmgh/maybeasencondword";
$breakstrings = explode('/',$SearchString);
foreach ($breakstrings as $values)
{
if(!strpos($file, $values))
{
echo $values." string not found!\n";
}
else
{
echo $values." string Found!\n";
}
But of a confusing title so let me explain. I have an array of links like this:
http://somesite.com/videoplayback?ip=81.0.0.0&sparams=id,expire,ip,ipbits,itag,algorithm,burst,factor&fexp=905602&algorithm=throttle-factor&itag=34&ipbits=8&burst=40&sver=3&expire=1285056000&key=yt1&signature=690F9475D5288F3129F84364427B2B490B6ACE59.45C8F83DEE3DD361855B12AE538EA6349FF8EF9B&factor=1.25&id=d50e6528eb51ad54,18
http://somesite.com/videoplayback?ip=81.0.0.0&sparams=id,expire,ip,ipbits,itag,algorithm,burst,factor&fexp=905602&algorithm=throttle-factor&itag=18&ipbits=8&burst=40&sver=3&expire=1285056000&key=yt1&signature=A68EAA3F7A2ECA2BB2BD6C35BF443C03E4BB1172.AD2FF9FDAF046B23F789FE1A7F7882DF9A355DE4&factor=1.25&id=d50e6528eb51ad54,5
http://somesite.com/videoplayback?ip=81.0.0.0&sparams=id,expire,ip,ipbits,itag,algorithm,burst,factor&fexp=905602&algorithm=throttle-factor&itag=5&ipbits=8&burst=40&sver=3&expire=1285056000&key=yt1&signature=ABC8ACF6899C46CC992ECB5F6A6FD7E66383EA3D.0C8B707083203DC1153FB26586A94BFAC64D176B&factor=1.25&id=d50e6528eb51ad54
If you look at the very end of those URL's, they have extensions like ,18, ,5 and there is one last link with no extension like this at all.
Now, I need to use the link that has the highest number on the end as possible later in my code. In this example I need to filter out the very first link, because it has the highest integer on the end (18).
I would use a series of if() blocks, but in this case the integers on the end can change so that's not a good solution.
So I basically need to go through my array, check which link has the highest integer at the end (note that it is only 2 digits in length) and then store it in another variable.
Can anyone provide some sample/psudo code on how to effectively do this?
Cheers.
This will work even if there are commas in other places in the URL:
$links = array("http://somesite.com/videoplayback?ip=81.0.0.0&sparams=id,expire,ip,ipbits,itag,algorithm,burst,factor&fexp=905602&algorithm=throttle-factor&itag=34&ipbits=8&burst=40&sver=3&expire=1285056000&key=yt1&signature=690F9475D5288F3129F84364427B2B490B6ACE59.45C8F83DEE3DD361855B12AE538EA6349FF8EF9B&factor=1.25&id=d50e6528eb51ad54,18", "http://somesite.com/videoplayback?ip=81.0.0.0&sparams=id,expire,ip,ipbits,itag,algorithm,burst,factor&fexp=905602&algorithm=throttle-factor&itag=18&ipbits=8&burst=40&sver=3&expire=1285056000&key=yt1&signature=A68EAA3F7A2ECA2BB2BD6C35BF443C03E4BB1172.AD2FF9FDAF046B23F789FE1A7F7882DF9A355DE4&factor=1.25&id=d50e6528eb51ad54,5", "http://somesite.com/videoplayback?ip=81.0.0.0&sparams=id,expire,ip,ipbits,itag,algorithm,burst,factor&fexp=905602&algorithm=throttle-factor&itag=5&ipbits=8&burst=40&sver=3&expire=1285056000&key=yt1&signature=ABC8ACF6899C46CC992ECB5F6A6FD7E66383EA3D.0C8B707083203DC1153FB26586A94BFAC64D176B&factor=1.25&id=d50e6528eb51ad54");
$max = 0;
$highestLink = "";
foreach ($links as $link) {
$data = explode(",", strrev($link));
$val = strrev($data[0]);
if (is_numeric($val)) {
$val = (int) $val;
if ($val > $max) {
$max = $val;
$highestLink = $link;
}
}
}
echo $max;
For the obfuscation award:
array_multisort(
array_map('intval',preg_replace('/^.*?(,([0-9]+))?$/','$2',$array)),
$array);
echo end($array);
I've spent half day trying to figure out this and finally I got working solution.
However, I feel like this can be done in simpler way.
I think this code is not really readable.
Problem: Find first non-repetitive character from a string.
$string = "abbcabz"
In this case, the function should output "c".
The reason I use concatenation instead of $input[index_to_remove] = ''
in order to remove character from a given string
is because if I do that, it actually just leave empty cell so that my
return value $input[0] does not not return the character I want to return.
For instance,
$str = "abc";
$str[0] = '';
echo $str;
This will output "bc"
But actually if I test,
var_dump($str);
it will give me:
string(3) "bc"
Here is my intention:
Given: input
while first char exists in substring of input {
get index_to_remove
input = chars left of index_to_remove . chars right of index_to_remove
if dupe of first char is not found from substring
remove first char from input
}
return first char of input
Code:
function find_first_non_repetitive2($input) {
while(strpos(substr($input, 1), $input[0]) !== false) {
$index_to_remove = strpos(substr($input,1), $input[0]) + 1;
$input = substr($input, 0, $index_to_remove) . substr($input, $index_to_remove + 1);
if(strpos(substr($input, 1), $input[0]) == false) {
$input = substr($input, 1);
}
}
return $input[0];
}
<?php
// In an array mapped character to frequency,
// find the first character with frequency 1.
echo array_search(1, array_count_values(str_split('abbcabz')));
Python:
def first_non_repeating(s):
for i, c in enumerate(s):
if s.find(c, i+1) < 0:
return c
return None
Same in PHP:
function find_first_non_repetitive($s)
{
for($i = 0; i < strlen($s); $i++) {
if (strpos($s, $s[i], $i+1) === FALSE)
return $s[i];
}
}
Pseudocode:
Array N;
For each letter in string
if letter not exists in array N
Add letter to array and set its count to 1
else
go to its position in array and increment its count
End for
for each position in array N
if value at potition == 1
return the letter at position and exit for loop
else
//do nothing (for clarity)
end for
Basically, you find all distinct letters in the string, and for each letter, you associate it with a count of how many of that letter exist in the string. then you return the first one that has a count of 1
The complexity of this method is O(n^2) in the worst case if using arrays. You can use an associative array to increase it's performance.
1- use a sorting algotithm like mergesort (or quicksort has better performance with small inputs)
2- then control repetetive characters
non repetetive characters will be single
repetetvives will fallow each other
Performance : sort + compare
Performance : O(n log n) + O(n) = O(n log n)
For example
$string = "abbcabz"
$string = mergesort ($string)
// $string = "aabbbcz"
Then take first char form string then compare with next one if match repetetive
move to the next different character and compare
first non-matching character is non-repetetive
This can be done in much more readable code using some standard PHP functions:
// Count number of occurrences for every character
$counts = count_chars($string);
// Keep only unique ones (yes, we use this ugly pre-PHP-5.3 syntax here, but I can live with that)
$counts = array_filter($counts, create_function('$n', 'return $n == 1;'));
// Convert to a list, then to a string containing every unique character
$chars = array_map('chr', array_keys($counts));
$chars = implode($chars);
// Get a string starting from the any of the characters found
// This "strpbrk" is probably the most cryptic part of this code
$substring = strlen($chars) ? strpbrk($string, $chars) : '';
// Get the first character from the new string
$char = strlen($substring) ? $substring[0] : '';
// PROFIT!
echo $char;
$str="abbcade";
$checked= array(); // we will store all checked characters in this array, so we do not have to check them again
for($i=0; $i<strlen($str); $i++)
{
$c=0;
if(in_array($str[$i],$checked)) continue;
$checked[]=$str[$i];
for($j=$i+1;$j<=strlen($str);$j++)
{
if($str[$i]==$str[$j])
{
$c=1;
break;
}
}
if($c!=1)
{
echo "First non repetive char is:".$str[$i];
break;
}
}
This should replace your code...
$array = str_split($string);
$array = array_count_values($array);
$array = array_filter($array, create_function('$key,$val', 'return($val == 1);'));
$first_non_repeated_letter = key(array_shift($array));
Edit: spoke too soon. Took out 'array_unique', thought it actually dropped duplicate values. But character order should be preserved to be able to find the first character.
Here's a function in Scala that would do it:
def firstUnique(chars:List[Char]):Option[Char] = chars match {
case Nil => None
case head::tail => {
val filtered = tail filter (_!=head)
if (tail.length == filtered.length) Some(head) else firstUnique(filtered)
}
}
scala> firstUnique("abbcabz".toList)
res5: Option[Char] = Some(c)
And here's the equivalent in Haskell:
firstUnique :: [Char] -> Maybe Char
firstUnique [] = Nothing
firstUnique (head:tail) = let filtered = (filter (/= head) tail) in
if (tail == filtered) then (Just head) else (firstUnique filtered)
*Main> firstUnique "abbcabz"
Just 'c'
You can solve this more generally by abstracting over lists of things that can be compared for equality:
firstUnique :: Eq a => [a] -> Maybe a
Strings are just one such list.
Can be also done using array_key_exists during building an associative array from the string. Each character will be a key and will count the number as value.
$sample = "abbcabz";
$check = [];
for($i=0; $i<strlen($sample); $i++)
{
if(!array_key_exists($sample[$i], $check))
{
$check[$sample[$i]] = 1;
}
else
{
$check[$sample[$i]] += 1;
}
}
echo array_search(1, $check);