Hello,

I am writing a small billing application to bill phone records. I would be having an array which would load and hold the tariff information. The array would be something like:

$Tariff

(

[prefix] = 91, [rate] = 0.51

[prefix] = 92, [rate] = 0.80

[prefix] = 94, [rate] = 0.25

[prefix] = 947, [rate] = 0.33

[prefix] = 65, [rate] = 0.12

[prefix] = 66, [rate] = 0.15

[prefix] = 965, [rate] = 0.52

)

Although I've only shown about 4 entries, the array can have about 25,000 Entries having country code / prefix and rate information.

Now, what I would like to do is, when I pick up a phone number to bill, I'd like to find the most significant match to bill the number. For instance, lets say, my phone number to be billed is:

$called_number = '94777191934';

As its clear, this number can be billed using either prefixes 94 or 947 (based on the tariff array), however, the most significant match is, 947, so the billing rate would be 0.33.

I need to find a way, that would effectively be able to find which prefix to use from the array to bill the number. If I use functions which allow to find the needle in the haystack [i.e, strstr()], then possible matches in this case would be 94, 947 and even 91, but what I'm looking for is, something that would only match at the beginning of the number, and the most significant match.

The requirement here is for find out a way that would be able to achieve this in a SUPER FAST way. I'd be requiring to process thousands of records every minute and matching part has to be executed very fast to avoid any bottlenecks. So what would be the most effective way to do it?

------------------------------------------------------------------------------------------------

Part 2:

As I mentioned earlier, the Tariff array can have about 25,000 entries in it. I've been wondering, perhaps it would be not a wise idea to search the entire array for a match.

Assuming the number to be billed is '94777191934', what I thought of doing is, create a second temporary array [$Tariff_Temp()] and copy all entries from $Tariff() to $Tariff_Temp that starts with '9'. This way, I'd have a small array to do the search and matching. Once the match has been found, then I clear the temp array, check the next number to be billed, and populate the temp array based the number again.

Is it a good idea to work this way? The primary purpose is to keep the dataset small and manageable to achieve efficiency and speed in processing. If its a good idea, then what is a best and fastest way to copy data from the Tariff array to the Temp array based on the above condition?

Any help appreciated.

Cheers

Shaf.

I am writing a small billing application to bill phone records. I would be having an array which would load and hold the tariff information. The array would be something like:

$Tariff

(

[prefix] = 91, [rate] = 0.51

[prefix] = 92, [rate] = 0.80

[prefix] = 94, [rate] = 0.25

[prefix] = 947, [rate] = 0.33

[prefix] = 65, [rate] = 0.12

[prefix] = 66, [rate] = 0.15

[prefix] = 965, [rate] = 0.52

)

Although I've only shown about 4 entries, the array can have about 25,000 Entries having country code / prefix and rate information.

Now, what I would like to do is, when I pick up a phone number to bill, I'd like to find the most significant match to bill the number. For instance, lets say, my phone number to be billed is:

$called_number = '94777191934';

As its clear, this number can be billed using either prefixes 94 or 947 (based on the tariff array), however, the most significant match is, 947, so the billing rate would be 0.33.

I need to find a way, that would effectively be able to find which prefix to use from the array to bill the number. If I use functions which allow to find the needle in the haystack [i.e, strstr()], then possible matches in this case would be 94, 947 and even 91, but what I'm looking for is, something that would only match at the beginning of the number, and the most significant match.

The requirement here is for find out a way that would be able to achieve this in a SUPER FAST way. I'd be requiring to process thousands of records every minute and matching part has to be executed very fast to avoid any bottlenecks. So what would be the most effective way to do it?

--------------------------

Part 2:

As I mentioned earlier, the Tariff array can have about 25,000 entries in it. I've been wondering, perhaps it would be not a wise idea to search the entire array for a match.

Assuming the number to be billed is '94777191934', what I thought of doing is, create a second temporary array [$Tariff_Temp()] and copy all entries from $Tariff() to $Tariff_Temp that starts with '9'. This way, I'd have a small array to do the search and matching. Once the match has been found, then I clear the temp array, check the next number to be billed, and populate the temp array based the number again.

Is it a good idea to work this way? The primary purpose is to keep the dataset small and manageable to achieve efficiency and speed in processing. If its a good idea, then what is a best and fastest way to copy data from the Tariff array to the Temp array based on the above condition?

Any help appreciated.

Cheers

Shaf.

$tarif['9']['4'] = 0.25;

$tarif['9']['4']['7'] = 0.33;

Then you can check the matching tarif like this:

$called_number = '94777191934';

if( isset( $tarif[$called_number[1]] ) )

{

if( isset( $tarif[$called_number[1]][

{

// make as many inner if's as the maximum prefix length

}

{

return $tarif[$called_number[1]][

}

}

else

{

return $tarif[$called_number[1]];

}

It is a fast way since you go directly to the matching number.

<?php

$calledNumber = '12345';

$len = strlen($calledNumber);

$searches = array();

for($i = 0; $i < $len; $i++) {

$searches[] = substr($calledNumber, 0, $i+1);

}

$query = 'SELECT * FROM tariff WHERE prefix IN("'.implode('","', $searches).'") ORDER BY prefix DESC LIMIT 1';

print_r($query);

?>

Because 947 > 94 you get the best match by ordering on the prefix high to low, and taking only the first match. This even works with arrays that have 9477 and 94, but not 947.

Kind regards

-r-

I presume your tariff and its 25000 entries are in some MySQL table, with a column for prefixes that you have indexed ON.

Let's assume that the prefix is stored as a text string. '94738...'

Assuming a phone number of '93657897' I would add a '9' at the end, getting '936578979'.

And I would take the 2 leftmost digits, '93'

Then run

SELECT prefix FROM tariff where (prefix between '93' and '936578979') ORDER by prefix desc

Since table is indexed on prefix, the query "between" will be very fast. you now can place the resulting values in a php array and work directly from here.

Talking about the solution I commented, there's another variant: use numbers instead of chars/strings. I don't know which one would be faster (probably indexing arrays by numbers). Then you can get the digit in a position like this:

$number_at_pos_x = ( $call_number / 10^(x-1) ) mod 10;

you might build a SQL function that would compute the legth of the leftmost common string between two strings, ie

would return 1 for ('9', '987543') and ('96', '987543'), would return 3 for ('987', '987543') and ('9876','987543') etc

If this function is optimized then running it on the sql server might be very efficient, because the volume of data you would get back from the (single) would be very low. In that case, the total result would probably be better than running the php on in-memory array (because you have to transfer the array from the SQL server to the php server, and then eat RAM on the php server)

Hmmm... I'm sure some regexp expert could work the corresponding regexp, and that would probably be very fast...

Part 2, you don't need to create the temp every time, you can just need to split the main array by the first N characters (if you want to get a smaller size). Then when a number comes in, you locate the array by substr(N, number)..

Please provide your email to receive a sample view!

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.