Need to write a code block which check is one string is a rotation of another.
Looked at loads of posts on here and it is all in Java or C++ but I need to do it in PHP.
I have tried a few different things, trying to work from the C++ and Java examples but I am not having any luck, here is my current code:
<?php
function isSubstring($s1, $s2) {
if(strlen($s1) != strlen($s2)) {
return false;
}
if(WHAT TO PUT HERE) {
echo "it is!";
} else {
echo "nope";
}
}
isSubstring("hello", "helol");
?>
Many ways available. Here one more using built-in function count_chars on both strings, and then comparing both resulting arrays :
function isSubstring($s1, $s2) {
if (strlen($s1) != strlen($s2)) {
echo "nope";
return;
}
$s1cnt = count_chars($s1, 1);
$s2cnt = count_chars($s2, 1);
if($s1cnt === $s2cnt) {
echo "it is!";
} else {
echo "nope";
}
}
Edit : as MonkeyZeus pointed out, beware of comparison with multibyte characters. It may bite a little bit :
isSubstring('crढap', 'paࢤrc');
will give true as answer. ढ is UTF-8 indian devanagari three byte char : E0 A2 A4 and ࢤ is also three byte chars (arabic) : E0 A4 A2, and the count_chars function counts the individual bytes. So it would be safe to use if chars are from only one language, else get some headache pills...
It seems to me that to manage this kind of things we need to have chars that are made of 3 bytes.
I would go for something like this:
function isSubstring($s1, $s2)
{
// If the strings match exactly then no need to proceed
if($s1 === $s2)
{
echo "it is!";
return;
}
elseif(strlen($s1) !== strlen($s2))
{
// Strings must be of equal length or else no need to proceed
echo "nope";
return;
}
// Put each character into an array
$s1 = str_split($s1);
$s2 = str_split($s2);
// Sort alphabetically based on value
sort($s1);
sort($s2);
// Triple check the arrays against one-another
if($s1 === $s2)
{
echo "it is!";
}
else
{
echo "nope";
}
}
Here is a multibyte safe function to compare the two strings:
function mb_isAnagram($s1, $s2) {
if (strlen($s1) != strlen($s2)) {
return false;
} else {
$c1 = preg_split('//u', $s1, null, PREG_SPLIT_NO_EMPTY);
$c2 = preg_split('//u', $s2, null, PREG_SPLIT_NO_EMPTY);
sort($c1);
sort($c2);
if ($c1 === $c2) {
return true;
} else {
return false;
}
}
}
You could split each string and sort it, like this:
$split1 = unpack("C*",$s1);
asort($split1);
Then you can traverse both arrays comparing the values.
<?php
function isRotationalString($str1,$str2){
$len = strlen($str1);
if($str1 === $str2){
return true;
}else{
if($len == strlen($str2)){
$flag = true;
for($i=0;$i<$len;$i++){
if($str1[0]==$str2[$i]){
$tst = $i;$start = true;break;
}
}
if($start){
for($j=0;$j<$len;$j++){
$m = $j+$tst;
if($m < $len){
if($str1[$j] != $str2[$m]){
$flag = false;break;
}
}else{
if($m>=$len)
{
$k = $m - $len;
if($str1[$j] != $str2[$k]){
$flag = false;break;
}
}
}
}
}else{
$flag = false;
}
return $flag;
}
}
}
echo isRotationalString("abcd","bcda")?'It is':'It is not';
?>
above script will check whether a string is a rotation of another string or not?
isRotationalString("abcd","bcda") => It is
isRotationalString("abcd","cbda") => It is Not
This is the function for string rotation.
echo isRotationalString("abcdef","efabcd")?'It is':'It is not';
function isRotationalString($str1,$str2){
$len = strlen($str1);
if($str1 === $str2){
return true;
} else {
if($len == strlen($str2)) {
$stringMatchedArr1 = $stringMatchedArr2 = [];
for($i=0; $i<$len; $i++) {
$substr = substr($str1,$i );
$pos = strpos($str2, $substr);
if($pos !== false) {
$stringMatchedArr1[] = $substr;
}
}
for($j=1; $j <= $len; $j++) {
$substr = substr($str1, 0, $j );
$pos = strpos($str2, $substr);
if($pos !== false) {
$stringMatchedArr2[] = $substr;
}
}
foreach($stringMatchedArr2 as $string1) {
foreach($stringMatchedArr1 as $string2) {
if($string1.$string2 == $str1)
return true;
}
}
}
}
}
I would sort the characters in the strings by making it an array and then imploding them to a string again.
if (sort(str_split($s1)) == sort(str_split($s2))) {
That would do the trick in one line.
Edit: Thanks Don't Panic, edited my answer!
Related
I'm reading overflow for years but never had to post anything (thanks to great answers) until now because i can't rly find solution for my problem.
I'm kinda new to PHP.
So I'm creating game where you have to find a longest word with 12 random generated letters. I actually did this successfully in C# and Java, but now I'm porting some of code to PHP because i'm working on multiplayer version and some stuff will be on server.
So i did all this using this great thread (Answer by Thomas Jungblut):
Find the longest word given a collection
Now i tried to do same in PHP but, it's weird for me. I get some crazy result's and i dont know how to replicate this java method in php:
arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
I'm not getting any error, but obvisuly thing is not working, is there anyone that can maybe help me to work this out?
UPDATE: BTW, i know post might be confusing im new to posting here...so forgive me ^^
I "fixed" code, it will now find me longest word. But there is bug somewhere. Bug is allowing algortithm to use one character more than once, which should not be possible.
I think problem is here:
$newDict[$index] = array_splice($allowedCharacters, $index +1, count($allowedCharacters) - ($index +1));
This is my Current Code:
parse_dictionary.php
<?php
$ouput = array();
$mysqli = new mysqli('localhost','root','','multiquiz_db');
$mysqli->set_charset('utf8');
if ($result = $mysqli->query("SELECT word FROM words_live")) {
while($row = $result->fetch_array(MYSQL_ASSOC)) {
//echo(mb_convert_encoding($row['word'], 'HTML-ENTITIES', 'utf-8'));
array_push($ouput, $row['word']);
}
//echo utf8_decode(json_encode($ouput));
}
$result->close();
$mysqli->close();
?>
Trie.php
<?php
class Trie
{
public $children = array();
public $value = null;
public $word = null;
public function __construct($value = null)
{
$this->value = $value;
}
public function adda($array)
{
$this->addb($array, 0);
}
public function addb($array, $offset)
{
foreach ($this->children as $child)
{
if($child->value == $array[$offset])
{
$child->addb($array, $offset + 1);
return;
}
}
$trieNode = new Trie($array[$offset]);
array_push($this->children, $trieNode);
if($offset < count($array) - 1)
{
$trieNode->addb($array, $offset+1);
}
else
{
$trieNode->word = implode(" ", $array);
}
}
}
?>
Index.php
<?php
include 'Trie.php';
include 'parse_dictionary.php';
ini_set('memory_limit', '1024M'); // or you could use 1G
header('Content-Type: text/html; charset=utf-8');
mb_internal_encoding("UTF-8");
class LongestWord
{
public $root = null;
public function __construct($ouput)
{
$this->root = new Trie();
foreach ($ouput as $word)
{
//echo($word);
//echo(str_split_unicode($word)[0]);
$this->root->adda(str_split_unicode($word));
}
}
public function search($cs)
{
return $this->visit($this->root, $cs);
}
function visit($n, $allowedCharacters)
{
$bestMatch = null;
if(count($n->children) == 0)
{
$bestMatch = $n->word;
}
foreach($n->children as $child)
{
if($this->contains($allowedCharacters, $child->value))
{
$result = $this->visit($child, $this->remove($allowedCharacters, $child->value));
if($bestMatch == null || $result != null && strlen($bestMatch) < strlen($result))
{
$bestMatch = $result;
}
}
}
return $bestMatch;
}
function remove($allowedCharacters, $value)
{
$newDict = $allowedCharacters;
if(($key = array_search($value, $newDict)))
{
unset($newDict[$key]);
}
return $newDict;
}
function contains($allowedCharacters, $value)
{
foreach($allowedCharacters as $x)
{
if($value == $x)
{
// echo $value . "=====". $x. "|||||||";
return true;
}
else
{
//echo $value . "!!===". $x. "|||||||";
}
}
return false;
}
}
function str_split_unicode($str, $l = 0) {
if ($l > 0) {
$ret = array();
$len = mb_strlen($str, "UTF-8");
for ($i = 0; $i < $len; $i += $l) {
$ret[] = mb_substr($str, $i, $l, "UTF-8");
}
return $ret;
}
return preg_split("//u", $str, -1, PREG_SPLIT_NO_EMPTY);
}
$chars = 'IIOIOFNČGDĆJ';
$testCharacters = str_split_unicode($chars);
$lw = new LongestWord($ouput);
echo($lw->search($testCharacters));
?>
As you're using MySQL, here's an approach that will let the DB server do the work.
It's a bit dirty, because you have to add several WHERE conditions with regex matching, which will have a rather poor performance. (Unfortunately, I could not come up with a regex that would require all of the letters in one expression, but I'd be happy to be corrected.)
However, I have tested it on a database table of >200000 entries; it delivers results within less than 0.3 sec.
SELECT word
FROM words_live
WHERE
word REGEXP "a" AND
word REGEXP "b" AND
word REGEXP "c" AND
word REGEXP "d"
ORDER BY LENGTH(word) DESC
LIMIT 1;
Obviously, you must generate one word REGEXP "a" condition per letter in your PHP code when constructing the query.
The query should then give you exactly one result, namely the longest word in the database containing all of the characters.
I solved problem with this function, full working code updated in question post
function remove($allowedCharacters, $value)
{
$newDict = $allowedCharacters;
if(($key = array_search($value, $newDict)))
{
unset($newDict[$key]);
}
return $newDict;
}
removed old one:
function remove($allowedCharacters, $value)
{
$newDict = [count($allowedCharacters) - 1];
$index = 0;
foreach($allowedCharacters as $x)
{
if($x != $value)
{
$newDict[$index++] = $x;
}
else
{
//we removed the first hit, now copy the rest
break;
}
}
//System.arraycopy(allowedCharacters, index + 1, newDict, index, allowedCharacters.length - (index + 1)); JAVA arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
//$newDict[$index] = array_splice($allowedCharacters, $index +1, count($allowedCharacters) - ($index +1));
//$newDict = $allowedCharacters;
return $newDict;
}
I want to put the input like "RKKRRRRK" and try to get the output like largest continuous segment.. Suppose my input may be "RKKKR" then my program will display 'KKK' is the largest continuous segment.. and then it also display the count is 3..
I've already write the code for counting 'R' values.. now i want this program also... need help anyone help me.. thanks in advance.
Here the code:-
<?php
function numberOfR($string1)
{
for($i=0;$i <strlen($string1);$i++)
{
if($string1[$i]!='K')
{
$count++;
}
}
return $count;
}
$return_value= numberOfR("RKKRK");
echo "R's count is:";
echo $return_value;
?>
<?php
function getLongetSegment($string) {
$currentSegmentChar='';
$currentSegment="";
$biggestSegment="";
$current_length=0;
$biggest_length=0;
for($i=0;$i<strlen($string);$i++) {
$char = $string[$i];
if($char != $currentSegmentChar || $currentSegmentChar == '') {
if($current_length >= $biggest_length) {
$biggestSegment = $currentSegment;
$biggest_length = $current_length;
}
$currentSegmentChar = $char;
$currentSegment = $char;
$current_length = 1;
}
elseif($currentSegmentChar != '') {
$currentSegment .= $char;
$current_length++;
}
}
if($current_length >= $biggest_length) {
$biggestSegment = $currentSegment;
}
return array("string" => $biggestSegment,"length" => $biggest_length);
}
print_r(getLongetSegment("RKKRGGG"));
?>
Result: GGG
You can use preg_match_all over here as
preg_match_all('/(.)\1+/i','RKKRRRRK',$res);
usort($res[0],function($a,$b){
return strlen($b) - strlen($a);
});
echo $res[0][0];
Not sure if I understood this quite right. Something like this:
function maxCharSequece($string1)
{
$maxSeq = $seq = 0;
$maxChar = $lastChar = null;
for( $i = 0; $i < strlen($string1); $i++ )
{
$c = $string1[$i];
if (!$lastChar) $lastChar = $c;
if ( $lastChar == $c ){
if ( ++$seq > $maxSeq ) $maxChar = $lastChar;
}
else {
$maxSeq = $seq;
$seq = 0;
}
}
return $maxChar;
}
You can use preg_replace_callback to receive all continuous segments and select the longest
$sq = '';
preg_replace_callback('/(.)\1+/',
function ($i) use (&$sq) {
if(strlen($i[0]) > strlen($sq)) $sq = $i[0];
}, $str);
echo $sq . " " . strlen($sq);
I would like to print pattern of 3 characters using PHP. Like aaa, aab, aac .... zzz.
Now, I am using these PHP code but it is printing randomly instead sequence.
$i = 1;
$chars = array("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");
while($i > 0){ $current = $chars[rand(0,25)].$chars[rand(0,25)].$chars[rand(0,25)]; }
Quick but sloppy
$i=0;
$j=0;
$k=0;
while($i<26){
while($j<26){
while($k<26){
echo $chars[$i] . $chars[$j] . $chars[$k];
$k++;
}
$j++;
$k=0;
}
$i++;
$j=0;
$k=0;
}
Count from 0 to 26^3 -1. Then convert your numbers to base 26 , replace numbers by letters as needed, and prefix with "a" or "aa" if the converted result is single or double digit.
Use this function: string base_convert ( string $number , int $frombase , int $tobase )
I am not going to code it all out for you. You need to learn from it.
I got it in c#.
string sample = "AAA";
char[] chars = sample.ToCharArray();
char first = chars[0];
char second = chars[1];
char third = chars[2];
if (first == second && first == third)
{
third++;
bool isAlphaBet = Regex.IsMatch(third.ToString(), "[a-z]", RegexOptions.IgnoreCase);
if (isAlphaBet)
{
return $"{first}{second}{third}";
}
return $"empty";
}
if (first == second && first != third)
{
third++;
bool isAlphaBet = Regex.IsMatch(third.ToString(), "[a-z]", RegexOptions.IgnoreCase);
if (isAlphaBet)
{
return $"{first}{second}{third}";
}
else
{
second++;
third = 'A';
return $"{first}{second}{third}";
}
}//"ABA";
if (first != second && first == third)
{
third++;
bool isAlphaBet = Regex.IsMatch(third.ToString(), "[a-z]", RegexOptions.IgnoreCase);
if (isAlphaBet)
{
return $"{first}{second}{third}";
}
else
{
second++;
third = 'A';
return $"{first}{second}{third}";
}
}
if (first != second && first != third && second != third)
{
third++;
bool isAlphaBet = Regex.IsMatch(third.ToString(), "[a-z]", RegexOptions.IgnoreCase);
if (isAlphaBet)
{
return $"{first}{second}{third}";
}
else
{
second++;
third = 'A';
bool isAlphaBetSecond = Regex.IsMatch(second.ToString(), "[a-z]", RegexOptions.IgnoreCase);
if (isAlphaBetSecond)
{
return $"{first}{second}{third}";
}
else
{
second = 'A';
first++;
bool isAlphaBetFirst = Regex.IsMatch(first.ToString(), "[a-z]", RegexOptions.IgnoreCase);
if (isAlphaBetFirst)
{
return $"{first}{second}{third}";
}
else
{
return $"empty";
}
}
}
}
if (first != second && second == third)
{
third++;
bool isAlphaBetThird = Regex.IsMatch(third.ToString(), "[a-z]", RegexOptions.IgnoreCase);
if (isAlphaBetThird)
{
return $"{first}{second}{third}";
}
else
{
third = 'A';
second++;
bool isAlphaBetSecond = Regex.IsMatch(second.ToString(), "[a-z]", RegexOptions.IgnoreCase);
if (isAlphaBetSecond)
{
return $"{first}{second}{third}";
}
else
{
second = 'A';
first++;
bool isAlphaBetFirst = Regex.IsMatch(first.ToString(), "[a-z]", RegexOptions.IgnoreCase);
if (isAlphaBetFirst)
{
return $"{first}{second}{third}";
}
else
{
return $"empty";
}
}
}
}
return $"{first}{second}{third}";
If you need to print random - like 'aaa' or 'vvv' or 'ddd' - try to use
$char = $chars[rand(0,25)];
echo $current = $char.$char.$char;
If you want to print 'aaa','bbb','ccc',...- use
for ($i = 0; $i < 26; $i++) {
$char = $chars[$i];
echo $current = $char.$char.$char;
}
I have this PHP code which is supposed to increase a URL shortener mask on each new entry.
My problem is that it dosen't append a new char when it hits the last one (z).
(I know incrementing is a safety issue since you can guess earlier entries, but this is not a problem in this instance)
If i add 00, it can figure out 01 and so on... but is there a simple fix to why it won't do it on its own?
(The param is the last entry)
<?php
class shortener
{
public function ShortURL($str = null)
{
if (!is_null($str))
{
for($i = (strlen($str) - 1);$i >= 0;$i--)
{
if($str[$i] != 'Z')
{
$str[$i] = $this->_increase($str[$i]);
#var_dump($str[$i]);
break;
}
else
{
$str[$i] = '0';
if($i == 0)
{
$str = '0'.$str;
}
}
}
return $str;
}
else {
return '0';
}
}
private function _increase($letter)
{
//Lowercase: 97 - 122
//Uppercase: 65 - 90
// 0 - 9 : 48 - 57
$ord = ord($letter);
if($ord == 122)
{
$ord = 65;
}
elseif ($ord == 57)
{
$ord = 97;
}
else
{
$ord++;
}
return chr($ord);
}
}
?>
Effectively, all you are doing is encoding a number into Base62. So if we take the string, decode it into base 10, increment it, and reencode it into Base62, it will be much easier to know what we are doing, and the length of the string will take care of itself.
class shortener
{
public function ShortURL($str = null)
{
if ($str==null) return 0;
$int_val = $this->toBase10($str);
$int_val++;
return $this->toBase62($int_val);
}
public function toBase62($num, $b=62) {
$base='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$r = $num % $b ;
$res = $base[$r];
$q = floor($num/$b);
while ($q) {
$r = $q % $b;
$q =floor($q/$b);
$res = $base[$r].$res;
}
return $res;
}
function toBase10( $num, $b=62) {
$base='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$limit = strlen($num);
$res=strpos($base,$num[0]);
for($i=1;$i<$limit;$i++) {
$res = $b * $res + strpos($base,$num[$i]);
}
return $res;
}
}
I have a large number of strings to process in php. I want to "fix" them to be title case (using ucwords(strtolower($str))) but only if they are all upper or all lower case already. If they are already mixed case, I'd just rather just leave them as they are.
What is the fastest way to check for this? It seems like foring through the string would be a rather slow way to go about it.
Here's what I have, which I think will be too slow:
function fixCase($str)
{
$uc = 0;
$lc = 0;
for($i=0;$i<strlen($str);$i++)
{
if ($str[$i] >= 'a' && $str[$i] <= 'z')
$lc++;
else if ($str[$i] >= 'A' && $str[$i] <= 'Z')
$uc++;
}
if ($uc == 0 || $lc == 0)
{
return ucwords(strtolower($str));
}
}
just use a string compare (case sensitive)
function fixCase($str)
{
if (
(strcmp($str, strtolower($str)) === 0) ||
(strcmp($str, strtoupper($str)) === 0) )
{
$str = ucwords(strtolower($str));
}
return $str;
}
There's not going to be any amazing optimization, because by the nature of the problem you need to look at every character.
Personally, I would just loop over the characters of the string with this sort of algorithm:
Look at the first character in the string, set a variable indicating whether it was upper or lowercase.
Now examine each character sequentially. If you get to the end of the string and they've all been the same case as the first character, fix the string's case as you like.
If any character is a different case than the first character was, break the loop and return the string.
Edit: actual code, I think this is about as good as you're going to get.
// returns 0 if non-alphabetic char, 1 if uppercase, 2 if lowercase
function getCharType($char)
{
if ($char >= 'A' && $char <= 'Z')
{
return 1;
}
else if ($char >= 'a' && $char <= 'z')
{
return 2;
}
else
{
return 0;
}
}
function fixCase($str)
{
for ($i = 0; $i < strlen($str); $i++)
{
$charType = getCharType($str[$i]);
if ($charType != 0)
{
$firstCharType = $charType;
break;
}
}
for ($i = $i + 1; $i < strlen($str); $i++)
{
$charType = getCharType($str[$i]);
if ($charType != $firstCharType && $charType != 0)
{
return $str;
}
}
if ($firstCharType == 1) // uppercase, need to convert to lower first
{
return ucwords(strtolower($str));
}
else if ($firstCharType == 2) // lowercase, can just ucwords() it
{
return ucwords($str);
}
else // there were no letters at all in the string, just return it
{
return $str;
}
}
You could try the string case test function I posted here
function getStringCase($subject)
{
if (!empty($subject))
{
if (preg_match('/^[^A-Za-z]+$/', $subject))
return 0; // no alphabetic characters
else if (preg_match('/^[^A-Z]+$/', $subject))
return 1; // lowercase
else if (preg_match('/^[^a-z]+$/', $subject))
return 2; // uppercase
else
return 3; // mixed-case
}
else
{
return 0; // empty
}
}
If the reason you want to avoid fixing already mixed-case strings is for efficiency then you are likely wasting your time, convert every string no matter its current condition:
function fixCase($str)
{
return ucwords(strtolower($str));
}
I would be very surprised if it ran any slower than the accepted answer for strings the length of those you would generally want to title case, and it's one less condition you need to worry about.
If, however, there is good reason to avoid converting already mixed-case strings, for example you want to preserve some intended meaning in the casing, then yes, jcinacio's answer is certainly the simplest and very efficient.
Wouldn't it be easier to check if the string = lowercase(string) or string = uppercase(string) and if so then leave it. Otherwise perform your operation.
Well I decided to do a test of the 2 proposed answers thus far and my original solution. I wouldn't have thought the results would turn out this way, but I guess native methods are /that/ much faster over all.
Code:
function method1($str)
{
if (strcmp($str, strtolower($str)) == 0)
{
return ucwords($str);
}
else if (strcmp($str, strtoupper($str)) == 0)
{
return ucwords(strtolower($str));
}
else
{
return $str;
}
}
// returns 0 if non-alphabetic char, 1 if uppercase, 2 if lowercase
function getCharType($char)
{
if ($char >= 'A' && $char <= 'Z')
{
return 1;
}
else if ($char >= 'a' && $char <= 'z')
{
return 2;
}
else
{
return 0;
}
}
function method2($str)
{
for ($i = 0; $i < strlen($str); $i++)
{
$charType = getCharType($str[$i]);
if ($charType != 0)
{
$firstCharType = $charType;
break;
}
}
for ($i = $i + 1; $i < strlen($str); $i++)
{
$charType = getCharType($str[$i]);
if ($charType != $firstCharType && $charType != 0)
{
return $str;
}
}
if ($firstCharType == 1) // uppercase, need to convert to lower first
{
return ucwords(strtolower($str));
}
else if ($firstCharType == 2) // lowercase, can just ucwords() it
{
return ucwords($str);
}
else // there were no letters at all in the string, just return it
{
return $str;
}
}
function method0($str)
{
$uc = 0;
$lc = 0;
for($i=0;$i<strlen($str);$i++)
{
if ($str[$i] >= 'a' && $str[$i] <= 'z')
$lc++;
else if ($str[$i] >= 'A' && $str[$i] <= 'Z')
$uc++;
}
if ($uc == 0 || $lc == 0)
{
return ucwords(strtolower($str));
}
}
function test($func,$s)
{
$start = gettimeofday(true);
for($i = 0; $i < 1000000; $i++)
{
$s4 = $func($s);
}
$end = gettimeofday(true);
echo "$func Time: " . ($end-$start) . " - Avg: ".sprintf("%.09f",(($end-$start)/1000000))."\n";
}
$s1 = "first String";
$s2 = "second string";
$s3 = "THIRD STRING";
test("method0",$s1);
test("method0",$s2);
test("method0",$s3);
test("method1",$s1);
test("method1",$s2);
test("method1",$s3);
test("method2",$s1);
test("method2",$s2);
test("method2",$s3);
Results:
method0 Time: 19.2899270058 - Avg: 0.000019290
method0 Time: 20.8679389954 - Avg: 0.000020868
method0 Time: 24.8917310238 - Avg: 0.00002489
method1 Time: 3.07466816902 - Avg: 0.000003075
method1 Time: 2.52559089661 - Avg: 0.000002526
method1 Time: 4.06261897087 - Avg: 0.000004063
method2 Time: 19.2718701363 - Avg: 0.000019272
method2 Time: 35.2485661507 - Avg: 0.000035249
method2 Time: 29.3357679844 - Avg: 0.000029336
Note that anything that looks only at [A-Z] will be incorrect as soon as there are accented or umlaut characters. Optimizing for speed is meaningless if the result is incorrect (hey, if the result doesn't have to be correct, it can write you a REALLY fast implementation...)