Display frequency of n-letter digits - java

Hi I'm trying to display the number of all three and five letter words from a text file called Article.txt but the output I get is 4 for both. I am a beginner and I will appreciate any kind of help. Thank you!
import java.util.*;
import java.io.*;
class test
{
public static void main(String[] args) throws Exception
{
FileReader fr = new FileReader("E:\\test\\Article.txt");
Scanner s = new Scanner(fr);
String str = s.nextLine();
String[] words = str.split(" ");
int countThree = 0, countFive = 0;`
for(String word : words)
{
if(word.length() == 3)
{
countThree++;
}
else if(word.length() == 5)
{
countFive++;
}
}
System.out.println("Number of three letter words: " +countThree);
System.out.println("Number of five lettr words: " +countFive);
}
}
Here is the article:
There was a time when Pete Sampras tally of 14 Grand Slam singles titles the last of which came at the US Open in 2002 seemed like the acme of sporting
achievement in men tennis. Little did anybody expect that in the next 16 years across 64 Majors not one or two but three players would stand shoulder to
shoulder with the American great. On Sunday Novak Djokovic became that third man defeating Argentine Juan Martin del Potro for his third US Open title at
Flushing Meadows. The 31 year old Serb has never been considered a once in a generation talent as have Roger Federer and Rafael Nadal the ones above him in
the trophy count. But nobody represents the modern day game as well as Djokovic. He is the ultimate practitioner of the attrition-based baseline tennis and at
his best with his supremely efficient patrolling of the court is near invincible. Over two weeks in New York he hit this high many times over. In fact
the 95-minute second set in the final was a microcosm of Djokovic last two years. It was long and weary as fortunes swung back and forth. But adversity
energised him and he found a level which his opponent could not match. Coming after his triumphant return at Wimbledon in July the latest success is evidence
enough that technically, tactically and physically Djokovic is back to his best.
If it was about the restoration of the old order on the mens side it was the continuation of the new in the women section. There has been a first time
winner in four of the past six Grand Slam tournaments and 20 year old Naomi Osaka added to the eclectic mix by becoming the first Japanese to win a Major.
In Serena Williams the winner of 23 singles Slams, the most by any player in the Open Era Osaka faced the ultimate challenge. It was also an inter generational
battle like none other. The 16 year age gap between Williams and Osaka was the second biggest in the Open Era for a womens final next only to Monica Seles
versus Martina Navratilova at the 1991 US Open. To her immense credit Osaka was not awed by the stage. While growing up she had revered Williams. After all
this is someone who chose Williams as her subject for a school essay in third grade. On Saturday she played like she knew the 36 year olds game like the back of
her hand absorbing everything the American threw at her and redirecting them with much more panache. The magnitude of her achievement was nearly drowned out by
the chaos in the aftermath of Williams tirade against the chair umpire. Yet the manner in which Osaka at an impressionable young age closed out the match with
a cold relentlessness showed she is here to stay.

I assume you would like to process your file by line.
At present you are only evaluating the first line by executing
String str = s.nextLine();
For this line you are counting the number of words.
You have to count also for all other lines.

Related

Android App Crushing Unexpectedly [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I want the user to be able to click on the app's button and get a random fact(String) from my FactBook.java's list. I am initializing the list when the app opens for the first time by calling the initFacts() method(static) and then check every time the user taps the button if the list is empty. If it is I must re-initialize the list so that it doesn't remain empty. However, the app crashes when I click on the button but I can't find the error, everything seems right to me. Can someone help me? Thank you in advance.
package com.spdesigns.funfacts;
import android.graphics.Color;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.RelativeLayout;
import android.widget.TextView;
import java.util.Random;
public class FunFactsActivity extends AppCompatActivity {
//private FactBook factBook = new FactBook();
private ColorWheel colorWheel = new ColorWheel();
// Declare our View vars
private RelativeLayout relativeLayout;
private TextView factTextView;
private Button showFactButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fun_facts);
// Assign the Views from the layout file to the corresponding variables
relativeLayout = (RelativeLayout) findViewById(R.id.relativeLayout);
factTextView = (TextView) findViewById(R.id.factTextView);
showFactButton = (Button) findViewById(R.id.showFactButton);
FactBook.initFacts();
View.OnClickListener listener = new View.OnClickListener() {
#Override
public void onClick(View v) {
// Update the screen with our new fact
int color = colorWheel.getColor();
relativeLayout.setBackgroundColor(color);
showFactButton.setTextColor(color);
factTextView.setText(FactBook.getFact());
}
};
showFactButton.setOnClickListener(listener);
}
}
FactBook.java
package com.spdesigns.funfacts;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
/**
* FunFacts was
* Created by Stelios Papamichail on 11/2/2017.
* <p>
* This file belongs to the com.spdesigns.funfacts package.
*/
class FactBook {
private static List<String> facts;
static void initFacts() {
facts = Arrays.asList("If you somehow found a way to extract all of the gold from the bubbling core of our lovely little planet, you would be able to cover all of the land in a layer of gold up to your knees.",
"McDonalds calls frequent buyers of their food “heavy users.",
"The average person spends 6 months of their lifetime waiting on a red light to turn green.",
"The largest recorded snowflake was in Keogh, MT during year 1887, and was 15 inches wide.",
"You burn more calories sleeping than you do watching television.",
"There are more lifeforms living on your skin than there are people on the planet.",
"Southern sea otters have flaps of skin under their forelegs that act as pockets. When diving, they use these pouches to store rocks and food.",
"In 1386 a pig in France was executed by public hanging for the murder of a child.",
"One in every five adults believes that aliens are hiding in our planet disguised as humans.",
"If you believe that you’re truly one in a million, there are still approximately 7,184 more people out there just like you.",
"A single cloud can weight more than 1 million pounds.",
"A human will eat on average 70 assorted insects and 10 spiders while sleeping.",
"James Buchanan, the 15th U.S. president continuously bought slaves with his own money in order to free them.",
"There are more possible iterations of a game of chess than there are atoms in the known universe.",
"The average person walks the equivalent of three times around the world in a lifetime.",
"Men are 6 times more likely to be struck by lightning than women.",
"Coca-Cola would be green if coloring wasn’t added to it.",
"You cannot snore and dream at the same time.",
"The world’s oldest piece of chewing gum is over 9,000 years old!",
"A coyote can hear a mouse moving underneath a foot of snow.",
"Bolts of lightning can shoot out of an erupting volcano.",
"New York drifts about one inch farther away from London each year.",
"A U.S. dollar bill can be folded approximately 4,000 times in the same place before it will tear.",
"A sneeze travels about 100 miles per hour.",
"Earth has traveled more than 5,000 miles in the past 5 minutes.",
"It would take a sloth one month to travel one mile.",
"10% of the World’s population is left handed.",
"A broken clock is right two times every day.",
"According to Amazon, the most highlighted books on Kindle are the Bible, the Steve Jobs biography, and The Hunger Games.",
"Bob Marley’s last words to his son before he died were “Money can’t buy life.",
"A mole can dig a tunnel that is 300 feet long in only one night.",
"A hippo’s wide open mouth is big enough to fit a 4-foot-tall child in.",
"Chewing gum while you cut an onion will help keep you from crying.",
"If you were to stretch a Slinky out until it’s flat, it would measure 87 feet long.",
"Al Capone’s business card said he was a used furniture dealer",
"There are more collect calls on Father’s Day than on any other day of the year.",
"Banging your head against a wall burns 150 calories an hour.",
"95% of people text things they could never say in person.",
"A crocodile can’t poke its tongue out.",
"It is physically impossible for pigs to look up into the sky.",
"Guinness Book of Records holds the record for being the book most often stolen from Public Libraries.",
"The word “gorilla” is derived from a Greek word meaning, “A tribe of hairy women.”" ,
"Prisoners in Canadian war camps during WWII were treated so well, that a lot of them didn’t’ want to leave when the war was over." ,
"Gorillas burp when they are happy " ,
"In New York, it is illegal to sell a haunted house without telling the buyer." ,
"In 2006 someone tried to sell New Zealand on eBay. The price got up to $3,000 before eBay shut it down." ,
"It is considered good luck in Japan when a sumo wrestler makes your baby cry." ,
"A man from Britain changed his name to Tim Pppppppppprice to make it harder for telemarketers to pronounce." ,
"A woman from California once tried to sue the makers of Cap’n Crunch, because the Crunch Berries contained “no berries of any kind.”" ,
"Apple launched a clothing line in 1986. It was described as a “train wreck” by others." ,
"In Japan, crooked teeth are considered cute and attractive." ,
"A Swedish woman lost her wedding ring, and found it 16 years later- growing on a carrot in her garden." ,
"Donald duck comics were banned from Finland because he doesn’t wear pants." ,
"The chance of you dying on the way to get lottery tickets is actually greater than your chance of winning." ,
"Cherophobia is the fear of fun." ,
"The toothpaste “Colgate” in Spanish translates to “go hang yourself”",
"Pirates wore earrings because they believed it improved their eyesight.",
"Human thigh bones are stronger than concrete." ,
"Cockroaches can live for several weeks with their heads cut off, because their brains are located inside their body. They would eventually die from being unable to eat." ,
"Scientists have tracked butterflies that travel over 3,000 miles." ,
"To produce a single pound of honey, a single bee would have to visit 2 million flowers." ,
"The population is expected to rise to 10.8 billion by the year 2080." ,
"You breathe on average about 8,409,600 times a year" ,
"More than 60,000 people are flying over the United States in an airplane right now." ,
"Hamsters run up to 8 miles at night on a wheel." ,
"A waterfall in Hawaii goes up sometimes instead of down." ,
"A church in the Czech Republic has a chandelier made entirely of human bones." ,
"Under the Code of Hammurabi, bartenders who watered down beer were punished by execution." ,
"Our eyes are always the same size from birth, but our nose and ears never stop growing." ,
"During your lifetime, you will produce enough saliva to fill two swimming pools." ,
"You are 1% shorter in the evening than in the morning" ,
"The elephant is the only mammal that can’t jump!" ,
"Most dust particles in your house are made from dead skin!",
"If 33 million people held hands, they could make it all the way around the equator." ,
"Earth is the only planet that is not named after a god." ,
"The bloodhound is the only animal whose evidence is admissible in court." ,
"You are born with 300 bones, but by the time you are an adult you only have 206." ,
"A ten-gallon hat will only hold ¾ of a gallon." ,
"Just like fingerprints, everyone has different tongue prints." ,
"ATM’s were originally thought to be failures, because the only users were prostitutes and gamblers who didn’t want to deal with tellers face to face." ,
"Of all the words in the English language, the word “set” has the most definitions. The word “run” comes in close second." ,
"A “jiffy” is the scientific name for 1/100th of a second." ,
"One fourth of the bones in your body are located in your feet" ,
"111,111,111 X 111,111,111 = 12,345,678,987,654,321" ,
"Blue-eyed people tend to have the highest tolerance of alcohol." ,
"A traffic jam lasted for more than 10 days, with cars only moving 0.6 miles a day." ,
"The tongue is the strongest muscle in the body." ,
"Every year more than 2500 left-handed people are killed from using right-handed products." ,
"More than 50% of the people in the world have never made or received a telephone call." ,
"The cigarette lighter was invented before the match.",
"A flea can jump up to 200 times its own height. That is the equivalent of a human jumping the Empire State Building." ,
"There are 5 temples in Kyoto, Japan that have blood stained ceilings. The ceilings are made from the floorboards of a castle where warriors killed themselves after a long hold-off against an army. To this day, you can still see the outlines and footprints." ,
"There is a snake, called the boomslang, whose venom causes you to bleed out from every orifice on your body. You may even turn blue from internal bleeding, and it can take up to 5 days to die from the bleeding." ,
"A ball of glass will bounce higher than a ball of rubber." ,
"Saturn’s density is low enough that the planet would float in water." ,
"68% of the universe is dark energy, and 27% is dark matter; both are invisible, even with our powerful telescopes. This means we have only seen 5% of the universe from earth." ,
"The founders of Google were willing to sell Google for $1 million to Excite in 1999, but Excite turned them down. Google is now worth $527 Billion." ,
"In the past 20 years, scientists have found over 1,000 planets outside of our solar system." ,
"There are 60,000 miles of blood vessels in the human body." ,
"If a pregnant woman has organ damage, the baby in her womb sends stem cells to help repair the organ." ,
"If you started with $0.01 and doubled your money every day, it would take 27 days to become a millionaire." ,
"Only one person in two billion will live to be 116 or older." ,
"A person can live without food for about a month, but only about a week without water.",
"If the amount of water in your body is reduced by just 1%, you’ll feel thirsty\n" +
"If it’s reduced by 10%, you’ll die." ,
"On average, 12 newborns will be given to the wrong parents daily." ,
"You can’t kill yourself by holding your breath."
);
}
static String getFact() {
// Randomly select a fact
if(facts.isEmpty()) {
initFacts();
}
Random randomGenerator = new Random();
int randomNumber= randomGenerator.nextInt(facts.size());
String fact = facts.get(randomNumber);
facts.remove(randomNumber);
return fact;
}
}
PS: I am thinking that the error could be caused because i'm trying to remove Strings from it in the getFact() method but I don't get why. Is it because the list is initialized inside a method making it's contents inaccessible?
Since you are using Arrays.asList to create your list, this list is unmodifiable, you cannot add or delete any element.
Arrays.asList: Returns a fixed-size list backed by the specified
array.
So when you get to the line
facts.remove(randomNumber);
you get an Exception like the following (just guessing because you have not shared any stacktrace or logs):
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.remove(AbstractList.java:161)
at blah.FactBook.getFact(FactBook.java:131)
...
To make your list modifiable create a new List object from the Arrays.asList, e.g.
facts = new ArrayList<String>(Arrays.asList("If you somehow found a way to extract all..."));

Assign same numbers in different formats to contact

How do I assign same numbers in different formats to one contact?
In the stock Samsung phone app,
+1 8542569, 8542569 and 18542569 are all assigned to one contact when called: "Example USA" :
Even though "Example USA" only has +1 854-256-9 listed in the phone book:
This goes on for every country, not just the USA. Here's a New Zealand example:
^ Here, "New Zealand Example" has 91234567 listed.
And, I can call 91234567, 00 64 9-123 4567 or 6491234567 and they will all get assigned to "New Zealand Example" contact:
My question is: how can I do the same thing in Java, for every country just like the Samsung stock app?
Say I have 3 strings: 91234567, 00 64 9-123 4567 and 6491234567.
How will my app recognize that they belong to the same contact and that they're basically the same number?
I'm sure it can be done because Samsung did it :)
Again, I'd like the code to work for every country.
Part 1: Remove starting zeros. They are useless. They might be useful, but it would be easier to do it by removing them.
This quora link with be a bit useful
Now countries have different number of digits in their phone numbers. Like, India has 10 which doesn't match New Zealand and USA.
Assuming that each country has a specific number of digits in numbers after removing region specific codes.
Part 2: You can create a multi-dimensional matrix, with country code and number of digits after that. Match for starting country codes, and then verify number of digits.
This method may have conflicts with different countries, but I lack knowledge about this thing.
Eg. of conflict:
Country A: country_code = +1, digits = 6
Country B: country_code = +12, digits =5
+1 234567
+12 34567

Group and count duplicate values in arraylist java

I have used ArrayLists in my application, so I do not want to move to HashMaps as I have seen a few answers using this but did not work in my case.
I am creating my final high school project which is a study time table scheduler. I have managed to sort the ArrayList by date of the exam, but now I am trying to analyze the time table to rate it and compare the ratings with other generated timetables to give the user the best timetable (with the highest value).
I have gotten the timetable to output what they will be doing on each day ie: Afrikaans, IT, LO, Maths, Afrikaans, Afrikaans, etc.
But it seems that it duplicates on the last one for a long time even if the two last exams are within 2 days or very close together, the last one will be more dominant in the entire list. Like this:
Exam Dates:
LO = 2 Sep
Maths = 5 Sep
IT = 9 Sep
Afrikaans = 10 Sep
Results:
LO
IT
Afrikaans
Maths
IT
Afrikaans
Afrikaans
Afrikaans
Afrikaans
As you can see, the result is much more weighted towards the last given subject.
Now I am trying to compare and group the data so I can see how many days were allocated to each subject, so using the above example I need it to look like this:
LO = 1
Maths = 1
IT = 2
Afrikaans = 5
So far I have this:
ArrayList<Day> days = new ArrayList<Day>();
For(int i = 0; i < timeTable.size(); i++) {
// need to group the days here
if(days.contains(timeTable.get(i))) {
days.get(i).incrementNumberOfDays();
} else {
days.add(timeTable.get(i));
}
}
But that is not grouping the data and counting the duplicates.
Please help, my project is due in a week and I have spent two months on it. I am almost finished and am stuck here.
Thanks in advance!
You can use java.util.Collections.frequency:
int count = Collections.frequency(timeTable, value);
Edit: answer to your last question in comment:
Surely there is a quick simple way to say this value occurred 3 times
in the arraylist?
It's necessary to mention that in your timeTable, assuming it contains two same Day - Afrikaans - 1, when you see they are the same, the contains function doesn't think so. Although they have the same value for each property, but not the hashcode.
You need to override the function of equals() to make sure that when comparing two Day, if they have the same value, they are regarded as one object.
Sorry for my poor English, hope you can get it.

random number different output every time

I am coding a secret santa program that prints out the unique secret santa of all participants and does not repeat the output on same input.
My problems are:
The program is generating same output on some reruns...
The program hangs after first run if more than or equal to 3 names present in the list. It prints correct output for only a few entries. For e.g. 3 names it prints secret santas of 2 names and hangs!
The code is as follows.
SecretSanta ss=new SecretSanta();
Scanner scn=new Scanner(System.in);
do
{
System.out.println("Add the participants name:-");
String name=scn.next().trim();
ss.names.add(name);
ss.santa.add(name);
System.out.println("Do u want to add more names?");
System.out.println(" 1-YES 2-NO");
choice=scn.nextInt();
}while(choice==1);
do
{
total_size=ss.santa.size();
System.out.println(total_size);
Collections.shuffle(ss.santa);
System.out.println(ss.names.size());
System.out.println("Below is the list of participants with their secret santas");
Iterator<?> itr=ss.names.iterator();
while(itr.hasNext())
{
String name=(String)itr.next();
String SecretName;
do
{
int rand=r.nextInt(total_size);
SecretName=ss.santa.get(rand);
}while(name.equals(SecretName));
System.out.println(name+" "+SecretName);
ss.santa.remove(SecretName);
total_size=ss.santa.size();
}
ss.santa.addAll(ss.names);
Collections.shuffle(ss.santa);
System.out.println("do you want to rerun??");
System.out.println(" 1-YES 2-NO");
choice=scn.nextInt();
}while(choice==1);
First of all, you can never be sure that a configuration does not repeat. There are just 6 permutations of 3 elements, so each 6th rerun (statistically) the configuration would repeat, assuming that you have 3 items in the list.
Next, about your hangs. You are removing items from the list, and then ask the program to find an element there. Imagine this situation: your names are Fred, Eric, Mike. The choices are
Fred - Eric
Eric - Fred
So you get only Mike in the list and only Mike in the list of santas. See the problem? There is no way to choose a santa. This can be solved in a few ways.
The most simple way is to shuffle names, assume that they are corresponding by indices and check whether anybody is santa for himself. If so, reshuffle. This still has the mentioned problem, but just for the list size one (in which case the problem obviously unsolvable).
The program is generating same output on some reruns because u are using random function and that function can produce repeated numbers (int rand=r.nextInt(total_size);).

What is the best way for converting phone numbers into international format (E.164) using Java?

What is the best way for converting phone numbers into international format (E.164) using Java?
Given a 'phone number' and a country id (let's say an ISO country code), I would like to convert it into a standard E.164 international format phone number.
I am sure I can do it by hand quite easily - but I would not be sure it would work correctly in all situations.
Which Java framework/library/utility would you recommend to accomplish this?
P.S. The 'phone number' could be anything identifiable by the general public - such as
* (510) 786-0404
* 1-800-GOT-MILK
* +44-(0)800-7310658
that last one is my favourite - it is how some people write their number in the UK and means that you should either use the +44 or you should use the 0.
The E.164 format number should be all numeric, and use the full international country code (e.g.+44)
Google provides a library for working with phone numbers. The same one they use for Android
http://code.google.com/p/libphonenumber/
String swissNumberStr = "044 668 18 00"
PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
try {
PhoneNumber swissNumberProto = phoneUtil.parse(swissNumberStr, "CH");
} catch (NumberParseException e) {
System.err.println("NumberParseException was thrown: " + e.toString());
}
// Produces "+41 44 668 18 00"
System.out.println(phoneUtil.format(swissNumberProto, PhoneNumberFormat.INTERNATIONAL));
// Produces "044 668 18 00"
System.out.println(phoneUtil.format(swissNumberProto, PhoneNumberFormat.NATIONAL));
// Produces "+41446681800"
System.out.println(phoneUtil.format(swissNumberProto, PhoneNumberFormat.E164));
Speaking from experience at writing this kind of thing, it's really difficult to do with 100% reliability. I've written some Java code to do this that is reasonably good at processing the data we have but won't be applicable in every country. Questions you need to ask are:
Are the character to number mappings consistent between countries? The US uses a lot of this (eg 1800-GOT-MILK) but in Australia, as one example, its pretty rare. What you'd need to do is ensure that you were doing the correct mapping for the country in question if it varies (it might not). I don't know what countries that use different alphabets (eg Cyrilic in Russia and the former Eastern block countries) do;
You have to accept that your solution will not be 100% and you should not expect it to be. You need to take a "best guess" approach. For example, theres no real way of knowing that 132345 is a valid phone number in Australia, as is 1300 123 456 but that these are the only two patterns that are for 13xx numbers and they're not callable from overseas;
You also have to ask if you want to validate regions (area codes). I believe the US uses a system where the second digit of the area code is a 1 or a 0. This may have once been the case but I'm not sure if it still applies. Whatever the case, many other countries will have other rules. In Australia, the valid area codes for landlines and mobile (cell) phones are two digits (the first is 0). 08, 03 and 04 are all valid. 01 isn't. How do you cater for that? Do you want to?
Countries use different conventions no matter how many digits they're writing. You have to decide if you want to accept something other than the "norm". These are all common in Australia:
(02) 1234 5678
02 1234 5678
0411 123 123 (but I've never seen 04 1112 3456)
131 123
13 1123
131 123
1 300 123 123
1300 123 123
02-1234-5678
1300-234-234
+44 78 1234 1234
+44 (0)78 1234 1234
+44-78-1234-1234
+44-(0)78-1234-1234
0011 44 78 1234 1234 (0011 is the standard international dialling code)
(44) 078 1234 1234 (not common)
And thats just off the top of my head. For one country. In France, for example, its common the write the phone number in number pairs (12 34 56 78) and they pronounce it that way too: instead of:
un (one), deux (two), trois (three), ...
its
douze (twelve), trente-quatre (thirty four), ...
Do you want to cater for that level of cultural difference? I would assume not but the question is worth considering just in case you make your rules too strict.
Also some people may append extension numbers on phone numbers, possibly with "ext" or similar abbreviation. Do you want to cater for that?
Sorry, no code here. Just a list of questions to ask yourself and issues to consider. As others have said, a series of regular expressions can do much of the above but ultimately phone number fields are (mostly) free form text at the end of the day.
This was my solution:
public static String FixPhoneNumber(Context ctx, String rawNumber)
{
String fixedNumber = "";
// get current location iso code
TelephonyManager telMgr = (TelephonyManager) ctx.getSystemService(Context.TELEPHONY_SERVICE);
String curLocale = telMgr.getNetworkCountryIso().toUpperCase();
PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
Phonenumber.PhoneNumber phoneNumberProto;
// gets the international dialling code for our current location
String curDCode = String.format("%d", phoneUtil.getCountryCodeForRegion(curLocale));
String ourDCode = "";
if(rawNumber.indexOf("+") == 0)
{
int bIndex = rawNumber.indexOf("(");
int hIndex = rawNumber.indexOf("-");
int eIndex = rawNumber.indexOf(" ");
if(bIndex != -1)
{
ourDCode = rawNumber.substring(1, bIndex);
}
else if(hIndex != -1)
{
ourDCode = rawNumber.substring(1, hIndex);
}
else if(eIndex != -1)
{
ourDCode = rawNumber.substring(1, eIndex);
}
else
{
ourDCode = curDCode;
}
}
else
{
ourDCode = curDCode;
}
try
{
phoneNumberProto = phoneUtil.parse(rawNumber, curLocale);
}
catch (NumberParseException e)
{
return rawNumber;
}
if(curDCode.compareTo(ourDCode) == 0)
fixedNumber = phoneUtil.format(phoneNumberProto, PhoneNumberFormat.NATIONAL);
else
fixedNumber = phoneUtil.format(phoneNumberProto, PhoneNumberFormat.INTERNATIONAL);
return fixedNumber.replace(" ", "");
}
I hope this helps someone with the same problem.
Enjoy and use freely.
Thanks for the answers. As stated in the original question, I am much more interested in the formatting of the number into the standard format than I am in determining if it is a valid (as in genuine) phone number.
I have some hand crafted code currently that takes a phone number String (as entered by the user) and a source country context and target country context (the country from where the number is being dialed, and the country to where the number is being dialed - this is known to the system) and then does the following conversion in steps
Strip all whitespace from the number
Translate all alpha into digits - using a lookup table of letter to digit (e.g. A-->2, B-->2, C-->2, D-->3) etc. for the keypad (I was not aware that some keypads distribute these differently)
Strip all punctuation - keeping a preceding '+' intact if it exists (in case the number is already in some sort of international format).
Determine if the number has an international dialling prefix for the country context - e.g. if source context is the UK, I would see if it starts with a '00' - and replace it with a '+'. I do not currently check whether the digits following the '00' are followed by the international dialing code for the target country. I look up the international dialing prefix for the source country in a lookup table (e.g. GB-->'00', US-->'011' etc.)
Determine if the number has a local dialing prefix for the country context - e.g. if the source context is the UK, I would look to see if it starts with a '0' - and replace it with a '+' followed by the international dialing code for the target country. I look up the local dialing prefix for the source country in a lookup table (e.g. GB-->'0', US-->'1' etc.), and the international dialing code for the target country in another lookup table (e.g.'GB'='44', US='1')
It seems to work for everything I have thrown at it so far - except for the +44(0)1234-567-890 situation - I will add a special case check for that one.
Writing it was not hard - and I can add special cases for each strange exception I come across. But I would really like to know if there is a standard solution.
The phone companies seem to deal with this thing every day. I never get inconsistent results when dialing numbers using the PSTN. For example, in the US (where mobile phones have the same area codes as landlines, I could dial +1-123-456-7890, or 011-1-123-456-7890 (where 011 is the international dialing prefix in the US and 1 is the international dialing code for the US), 1-123-456-7890 (where 1 is the local dialing prefix in the US) or even 456-7890 (assuming I was in the 123 area code at the time) and get the same results each time. I assume that internally these dialed numbers get converted to the same E.164 standard format, and that the conversion is all done in software.
To be honest, it sounds like you've got most of the bases covered already.
The +44(0)800 format sometimes (incorrectly) used in the UK is annoying and isn't strictly valid according to E.123, which is the ITU-T recommendation for how numbers should be displayed. If you haven't got a copy of E.123 it's worth a look.
For what it's worth, the telephone network itself doesn't always use E.164. Often there'll be a flag in the ISDN signalling generated by the PBX (or in the network if you're on a steam phone) which tells the network whether the number being dialled is local, national or international.
In some countries you can validate 112 as a valid phone number, but if you stick a country code in front of it it won't be valid any more. In other countries you can't validate 112 but you can validate 911 as a valid phone number.
I've seen some phones that put Q on the 7 key and Z on the 9 key. I've seen some phones that put Q and Z on the 0 key, and some that put Q and Z on the 1 key.
An area code that existed yesterday might not exist today, and vice-versa.
In half of North America (country code 1), the second digit rule used to be 0 or 1 for area codes, but that rule went away 10 years ago.
I'm not aware of a standard library or framework available for formatting telephone numbers into E.164.
The solution used for our product, which requires formatting PBX provided caller-id into E.164, is to deploy a file (database table) containing the E.164 format information for all countries applicable.
This has the advantage that the application can be updated (to handle all the strange corner cases in various PSTN networks) w/out requiring changes to the production code base.
The table contains a row for each country code and information regarding area code length and subscriber length. There may be multiple entries for a country depending on what variations are possible with area code and subscriber number lengths.
Using New Zealand PSTN (partial) dial plan as an example of the table..
CC AREA_CODE AREA_CODE_LENGTH SUBSCRIBER SUBSCRIBER_LENGTH
64 1 7
64 21 2 7
64 275 3 6
We do something similar to what you have described, i.e. strip the provided telephone number of any non-digit characters and then format based on various rules regarding overall number plan length, outside access code, and long distance/international access codes.

Categories

Resources