Sort only Numeric elements from String Array in java? - java

I am keen to sort only numeric elements that are in String array. I am doing it in java. Please help me to solve this Problem.
Here is my Problem
For the given set of characters, choose integers only and sort them in descending order and put in their position leaving other characters position intact.
The change is position should only be of integers not of other characters.
Sample Input:-
d,1,4,c,9,6
109,87,911,b,645
77,19,#,.,95
8,99,14,2,5,6,49
Sample Output:-
Case #1: d,9,6,c,4,1
Case #2: 911,645,109,b,87
Case #3: 95,77,#,.,19
Case #4: 99,49,14,8,6,5,2
Thank you to all viewer. Please would you all help me to solve this problem in Java
Here is my Code, I have tried So far.
import java.util.Arrays;
import java.util.Iterator;
import java.util.ArrayList;
class alphaNumeric {
public static void main(String a[]) {
String s1[] = new String[9];
ArrayList l_numList = new ArrayList();
ArrayList l_strList = new ArrayList();
s1[0] = "1000.1";
s1[1] = "100";
s1[2] = "xBC100";
s1[3] = "XBB100";
s1[4] = "TEST";
s1[5] = "AYZ2100";
s1[6] = "99";
s1[7] = "90";
s1[8] = "1000";
System.out.print("Before sorting, numbers are ");
for(int i = 0; i < s1.length; i++)
{
System.out.print(s1[i]+" ");
}
System.out.println();
for (int i = 0; i < s1.length; i++) {
if (isNumber(s1[i])) {
l_numList.add(s1[i]);
} else {
l_strList.add(s1[i]);
}
}
Object[] l_objArray = (Object[]) l_numList.toArray();
int l_intArray[] = new int[l_objArray.length];
for (int i = 0; i < l_objArray.length; i++) {
l_intArray[i] = Integer.parseInt((String) l_objArray[i]);
}
Arrays.sort(l_intArray);
for (int i = 0; i < l_intArray.length; i++) {
System.out.println("after Numsort: " + l_intArray[i]);
}
System.out.print("After sorting, numbers are ");
for(int i = 0; i < l_intArray.length; i++)
{
System.out.print(l_intArray[i]+" ");
}
Object[] l_strArray = (Object[]) l_strList.toArray();
Arrays.sort(l_strArray);
for (int i = 0; i < l_strArray.length; i++) {
System.out.println("after Strsort: " + l_strArray[i]);
}
}
static boolean isNumber(String s) {
String validChars = "0123456789";
boolean isNumber = true;
for (int i = 0; i < s.length() && isNumber; i++) {
char c = s.charAt(i);
if (validChars.indexOf(c) == -1) {
isNumber = false;
} else {
isNumber = true;
}
}
return isNumber;
}
}

I couldn't figure out what you were trying to do, but here's how I'd do it
Extract a List of only the Integers AND create List of indexes at which they occur in original array
Sort that List using standard reverse sort
Put sorted List values back into the original array, using index List
Working example
public class SortOnlyNumbers {
public static void main(String[] args) {
sortOnlyNumbers(new String[] { "d", "1", "4", "c", "9", "6" });
sortOnlyNumbers(new String[] { "109", "87", "911", "b", "645" });
sortOnlyNumbers(new String[] { "77", "19", "#", ".", "95" });
sortOnlyNumbers(new String[] { "8", "99", "14", "2", "5", "6", "49" });
}
private static void sortOnlyNumbers(String[] array) {
List<Integer> indexes = new ArrayList<Integer>();
List<Integer> numbers = new ArrayList<Integer>();
for (int i = 0; i < array.length; i++) {
try {
numbers.add(Integer.parseInt(array[i]));
indexes.add(i);
} catch (NumberFormatException e) {
// don't care
}
}
Collections.sort(numbers, Collections.reverseOrder());
for (int i = 0; i < numbers.size(); i++) {
array[indexes.get(i)] = String.valueOf(numbers.get(i));
}
System.out.println(Arrays.toString(array));
}
}
Output
[d, 9, 6, c, 4, 1]
[911, 645, 109, b, 87]
[95, 77, #, ., 19]
[99, 49, 14, 8, 6, 5, 2]

Related

Generate Permutations with Placeholders and Options

A bit complex challenge in Permutations for talented guys :)
Let's say we want to generate a Word using Placeholders (masks) for each part of the word.
In a word, we could have N Predefined placeholders (masks), let's call them Groups.
In each group we can have M values as options for the placeholder, let's call them Elements.
For instant, given a 3 parts word: [X][Y][Z].
[X] is a mask corresponding to the X Group.
meaning each Element (value) from the X Group
will take place in the permutations word.
same for Y and Z.
A concrete example for the 3 parts word is 1a!
out of 30 permutations of the following Groups and Elements below.
Please notice:
Order is important, GroupX then GroupY and so..
Group can have a "skip" option like Group "Y" in this example,
which means that permutations should also include a word from the type: [X][Z]
Total Permutations are Group1 X Group2 X G_n
(or in this example GroupX X GroupY X GroupZ)
GroupX: 1, 2, 3
GroupY: a, b, c, d, Skip
GroupZ: !, #
All the 30 permutations for [X][Y][Z] are:
1a!,
1a#,
1b!,
1b#,
1c!,
1c#,
1d!,
1d#,
2a!,
2a#,
2b!,
2b#,
2c!,
2c#,
2d!,
2d#,
3a!,
3a#,
3b!,
3b#,
3c!,
3c#,
3d!,
3d#
And also because the "skip" of group Y we will have those permutations:
1!,
1#,
2!,
2#,
3!,
3#,
Here's my code from this PAQ modified for chars:
import java.util.*;
import java.util.ArrayList;
class Main {
public static void main(String[] args) {
ArrayList<ArrayList<Character>> conditions = new ArrayList<ArrayList<Character>>();
ArrayList<Character> condition1 = new ArrayList<Character>();
condition1.add('1');
condition1.add('2');
condition1.add('3');
conditions.add(condition1);
ArrayList<Character> condition2 = new ArrayList<Character>();
condition2.add('a');
condition2.add('b');
condition2.add('c');
condition2.add('d');
condition2.add('\0');
conditions.add(condition2);
ArrayList<Character> condition3 = new ArrayList<Character>();
condition3.add('!');
condition3.add('#');
conditions.add(condition3);
System.out.println("Input Data:");
display(conditions);
System.out.println();
ArrayList<ArrayList<Character>> combos = findOptimalPairs(conditions);
System.out.println("Output Data:");
display(combos);
}
public static void display(ArrayList<ArrayList<Character>> data) {
for(ArrayList<Character> set : data) {
for(int i=0; i<set.size(); i++) {
System.out.print(set.get(i));
}
System.out.println();
}
}
public static ArrayList<ArrayList<Character>> findOptimalPairs(ArrayList<ArrayList<Character>> conditions) {
ArrayList<ArrayList<Character>> combos = new ArrayList<ArrayList<Character>>();
int combinations = 1;
int[] setSize = new int[conditions.size()];
for(int i=0; i<conditions.size(); i++) {
ArrayList<Character> set = conditions.get(i);
int size = set.size();
setSize[i] = size;
combinations = combinations * size;
}
int[] counters = new int[setSize.length];
for(int i=0; i<combinations; i++) {
ArrayList<Character> combo = new ArrayList<Character>();
for(int j=0; j<counters.length; j++) {
combo.add(conditions.get(j).get(counters[j]));
}
combos.add(combo);
for(int j=0; j<counters.length; j++) {
if (counters[j]<(setSize[j]-1)) {
counters[j]++;
break;
}
else {
counters[j] = 0;
}
}
}
return combos;
}
}
Producing the output:
Input Data:
123
abcd
!#
Output Data:
1a!
2a!
3a!
1b!
2b!
3b!
1c!
2c!
3c!
1d!
2d!
3d!
1!
2!
3!
1a#
2a#
3a#
1b#
2b#
3b#
1c#
2c#
3c#
1d#
2d#
3d#
1#
2#
3#
Here is one solution that I thought of.
any ideas for performance optimization?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
public class WordGen
{
public WordGen(string[][] Options)
{
this.options = Options;
this.words = new List<string>();
this.optionsCounter = countAllOptions();
}
private string[][] options;
private long optionsCounter;
private Dictionary<int, int> optionsPointers;
private bool endofOptions;
private List<string> words;
private long countAllOptions()
{
long optionsCount = 1;
foreach (string[] g in options)
{
optionsCount *= g.Length;
}
return optionsCount;
}
private void intOptionPointers()
{
optionsPointers = new Dictionary<int, int>();
for (int i = 0; i <= options.Length - 1; i++)
{
optionsPointers.Add(i, 0);
}
}
private void zeroOptionsPointers()
{
for (int i = options.Length - 1; i >= 0; i--)
{
if (optionsPointers[i] == options[i].Length - 1)
{
if (i == 0)
endofOptions = true;
else
optionsPointers[i] = 0;
}
else
{
optionsPointers[i]++;
return;
}
}
}
private void removeSkipChars()
{
IEnumerable<string> wordsWithsSkipChars = this.words.Where(w => w.Contains('-'));
foreach (string word in wordsWithsSkipChars)
{
int index = words.IndexOf(word);
words[index] = word.Trim('-');
}
}
private void buildWordsRec(StringBuilder word, int grpIndx)
{
int grpIndex = grpIndx;
while (!this.endofOptions)
{
//last group
if (grpIndex == options.Length - 1)
{
string fullWord = word.ToString() + options[grpIndex][optionsPointers[grpIndex]];
words.Add(fullWord);
System.Console.WriteLine("word: " + fullWord + " as " + words.Count + " out of " + this.optionsCounter);
//last element
if (optionsPointers[grpIndex] == options[grpIndex].Length - 1)
{
word.Clear();
zeroOptionsPointers();
grpIndex = 0;
}
else
{
optionsPointers[grpIndex]++;
}
}
else
{
word.Append(options[grpIndex][optionsPointers[grpIndex]]);
grpIndex++;
}
}
}
public List<string> GenerateWords()
{
StringBuilder word = new StringBuilder();
intOptionPointers();
buildWordsRec(word, 0);
removeSkipChars();
this.endofOptions = false;
return words;
}
public void WriteWordsToFile(string path)
{
System.IO.File.AppendAllLines(path, this.words);
}
public List<string> Words
{
get { return words; }
}
}
internal class Program
{
static void Main(string[] args)
{
string[] group1 = new string[] { "1","2","3" };
string[] group2 = new string[] { "a", "b", "c", "d", "-" };//"-" is act as Skip keyword
string[] group3 = new string[] { "!", "#"};
string[][] options = new string[][] { group1, group2, group3 };
WordGen pw = new WordGen(options);
pw.GenerateWords();
pw.WriteWordsToFile("D:\\words.txt");
System.Console.Read();
}
}

Sort array by value type

One array contains both numeric strings and mixed string values. How to sort this array and print numeric values first and remaining strings after?
String[] s = {"1","2","13","13a","10","10a","1a","1,"};
I want output like this --> 1 10 13 2 1, 10a 13a 1a
i am trying like this , and i got correct output but i want make it as easy way
import java.util.ArrayList;
import java.util.Arrays;
import java.util.regex.*;
public class sortprog {
public static void main(String[] args) {
String[] s={"1","2","13","13a","10","10a","1a","1,"};
ArrayList alnubers=new ArrayList();
ArrayList alstrings=new ArrayList();
int count=0;
for(int i=0;i<s.length;i++)
{
if(Pattern.matches("[0-9]+",s[i]))
{
alnubers.add(s[i]);
}
else
{
alstrings.add(s[i]);
}
}
/*for(int i=0;i<s.length;i++)
{
String str=s[i];
for ( int j = 0; j < str.length(); ++j )
{
char c = str.charAt(j);
int k = (int) c;
//System.out.println("ASCII OF "+c +" = " + k + ".");
if(k>=48&&k<=57)
{
count++;
}
else
{
count=0;
break;
}
}
if(count!=0)
{
alnubers.add(str);
count=0;
}
else
{
alstrings.add(str);
count=0;
}
}*/
String[] sarr = new String[alstrings.size()];
alstrings.toArray(sarr);
Arrays.sort(sarr);
String[] narr = new String[alnubers.size()];
alnubers.toArray(narr);
Arrays.sort(narr);
String[] finalarr=new String[sarr.length+narr.length];
for(int l=0;l<narr.length;l++)
{
finalarr[l]=narr[l];
}
int i=0;
for(int l=narr.length;l<sarr.length+narr.length;l++)
{
finalarr[l]=sarr[i];
i++;
}
for(int f=0;f<finalarr.length;f++)
{
System.out.println(finalarr[f]);
}
}
}
You can call sort with your own comparator:
String[] s = { "1", "2", "13", "13a", "10", "10a", "1a", "1," };
Arrays.sort(s, new Comparator<String>() {
#Override
public int compare(String arg0, String arg1) {
if (arg0.matches("\\d+")
&& !arg1.matches("\\d+")) {
return -1;
} else if (!arg0.matches("\\d+")
&& arg1.matches("\\d+")) {
return 1;
} else {
return 0;
}
}
});
System.out.println(Arrays.toString(s));
What this does is create a comparator that makes strings containing just digits (\\d) of lower order than things that don't, so they will come first when sorted.
You can put in any code you like in the comparator, so if you want to have a number followed by a comma first, then this is easy to do.

Compare and extract similar strings from 2 arrays in java, without duplication

I am trying to extract similar strings from 2 arrays, and I have managed to do so, except they are duplicating. i.e. array 1 {"arrow", "arrow", "sycophant"} and array 2 ("arrow", "sycophant", "bulbasaur"} will give me the output of {"arrow", "arrow" ,"sycophant"}, while I am only trying to get arrow once. Any suggestions?
public static void main(String[] args) {
String[] words1 = { "sycophant", "rattle", "zinc", "alloy", "tunnel", "arrow" };
String[] words2 = { "sycophant", "arrow", "arrow" };
// String prefix = "a";
// String substring = "at";
// char[] letters = { 'a', 'b' };
// String[] output = wordsStartingWith(words1, prefix);
// String[] output = wordsContainingPhrase(words1, substring);
// String[] output = wordsContainingAll(words1, letters);
String[] output = wordsInBoth(words1, words2);
for (int i = 0; i < output.length; i++) {
System.out.println("Words: " + i + " " + output[i]);
}
}
public static String[] wordsInBoth(String[] words1, String[] words2) {
// method that finds and returns common words in two arrays
String[] returnWords;
int countWords = 0;
for (int i = 0; i < words1.length; i++) {
for (int j = 0; j < words2.length; j++) {
if (words1[i].equalsIgnoreCase(words2[j])) {
countWords++;
}
}
}
returnWords = new String[countWords];
countWords = 0;
for (int i = 0; i < words1.length; i++) {
for (int j = 0; j < words2.length; j++) {
if (words1[i].equalsIgnoreCase(words2[j])
&& !words1[i].equalsIgnoreCase(returnWords[countWords])) {
returnWords[countWords] = words1[i];
countWords++;
}
}
}
return returnWords;
}
One possibility is to store the words that are found in a HashSet, which won't add duplicates.
// method that finds and returns common words in two arrays
public static String[] wordsInBoth(String[] words1, String[] words2) {
Set<String> returnWords = new HashSet<String>();
for (int i = 0; i < words1.length; i++) {
for (int j = 0; j < words2.length; j++) {
if (words1[i].equalsIgnoreCase(words2[j]))
returnWords.add(words1[i]);
}
}
return returnWords.toArray(new String[returnWords.size()]);
}
You want to get the intersection between two lists. The answer to Intersection and union of ArrayLists in Java should point you in the right direction:
public class Test {
public static void main(String... args) throws Exception {
List<String> list1 = new ArrayList<String>(Arrays.asList("A", "B", "C"));
List<String> list2 = new ArrayList<String>(Arrays.asList("B", "C", "D", "E", "F"));
System.out.println(new Test().intersection(list1, list2));
}
public <T> List<T> intersection(List<T> list1, List<T> list2) {
List<T> list = new ArrayList<T>();
for (T t : list1) {
if(list2.contains(t)) {
list.add(t);
}
}
return list;
}
}
In case you wonder why this
for (int i = 0; i < words1.length; i++)
for (int j = 0; j < words2.length; j++)
if (words1[i].equalsIgnoreCase(words2[j]) &&
!words1[i].equalsIgnoreCase(returnWords[countWords])
)
returnWords[countWords++] = words1[i];
doesn't work: it only a) attempts to check if words1[i] isn't the b) last word in returnWords.
a)
!words1[i].equalsIgnoreCase( returnWords[countWords] )
is always true, because returnWords[countWords] is always null. When countWords is 0 there are no words added to it yet, and when it is 1, the added word is at returnWords[0]. So you'll need something like this instead:
countWords == 0 || !words1[i].equalsIgnoreCase( returnWords[countWords-1] )
Now it works fine for your input (removed unique words):
String[] words1 = { "arrow", "sycophant" };
String[] words2 = { "arrow", "sycophant", "arrow" };
it outputs
Words: 0 arrow
Words: 1 sycophant
Words: 2 null
b)
For
String[] words1 = { "arrow", "sycophant", "arrow" };
String[] words2 = { "arrow", "sycophant" };
it outputs
Words: 0 arrow
Words: 1 sycophant
Words: 2 arrow
To prevent this, you would have to check whether the word about to be added isn't any of the already-added words:
!contains( returnWords, words1[j] )
This is a simple for-loop, which you know how to do - and there are plenty of examples on this page, so I'll leave that out.
Maybe this will help you. I have changed your algorithm a bit and now it looks like this.
import java.util.Arrays;
public class Distinct {
public static void main(String[] args) {
String[] words1 = { "sycophant", "rattle", "zinc", "alloy", "tunnel",
"arrow" };
String[] words2 = { "sycophant", "arrow", "alloy", "arrow" };
// String prefix = "a";
// String substring = "at";
// char[] letters = { 'a', 'b' };
// String[] output = wordsStartingWith(words1, prefix);
// String[] output = wordsContainingPhrase(words1, substring);
// String[] output = wordsContainingAll(words1, letters);
String[] output = wordsInBoth(words1, words2);
for (int i = 0; i < output.length; i++) {
System.out.println("Words: " + i + " " + output[i]);
}
}
public static String[] wordsInBoth(String[] words1, String[] words2) {
String[] returnWords;
int countWords = 0;
for (int i = 0; i < words1.length; i++) {
for (int j = 0; j < words2.length; j++) {
if (words1[i].equalsIgnoreCase(words2[j])) {
countWords++;
}
}
}
returnWords = new String[countWords];
countWords = 0;
for (int i = 0; i < words1.length; i++) {
for (int j = 0; j < words2.length; j++) {
if (words1[i].equalsIgnoreCase(words2[j]) && !exists(returnWords, words1[i])) {
returnWords[countWords] = words1[i];
countWords++;
}
}
}
return Arrays.copyOfRange(returnWords, 0, countWords);
}
public static boolean exists(String[] array, String value)
{
if (array.length == 0)
return false;
for(int i = 0; i < array.length; i++){
if (array[i]!= null && array[i].equalsIgnoreCase(value) )
return true;
}
return false;
}
}
Try this.
public static String[] wordsInBoth(String[] words1, String[] words2) {
return Stream.of(words1)
.filter(w -> Stream.of(words2).anyMatch(w::equalsIgnoreCase))
.toArray(String[]::new);
}
After a bit of fiddling around with the (primitive, slow and downright beginner :P) code I found a (messy) solution to my problems. XD
public static String[] wordsInBoth(String[] words1, String[] words2) {
// method that finds and returns common words in two arrays
String[] returnWords = new String[words1.length];
String compare = "";
int countWords = 0;
for (int i = 0; i < words1.length; i++) {
for (int j = 0; j < words2.length; j++) {
if (words1[i].equalsIgnoreCase(words2[j]) && words1[i] != compare) {
returnWords[countWords] = words1[i];
compare = returnWords[countWords];
countWords++;
}
}
}
returnWords = new String[countWords];
countWords = 0;
for (int i = 0; i < words1.length; i++) {
for (int j = 0; j < words2.length; j++) {
if (words1[i].equalsIgnoreCase(words2[j]) && words1[i] != compare) {
returnWords[countWords] = words1[i];
compare = returnWords[countWords];
countWords++;
}
}
}
return returnWords;
}
(also, I don't know why, but my method line is not included in the code snippet when I post to Stack)

Sort ArrayList using predefined list of indices

I am trying to sort an ArrayList using a predefined array of indices.
My current example uses a copy of the original ArrayList for sorting and therefore is not scalable for ArrayLists of larger objects
package sortExample;
import java.awt.List;
import java.util.ArrayList;
import java.util.Arrays;
public class sortExample {
public static void main(String[] args) {
String [] str = new String[] {"a","b","c","d"};
ArrayList<String> arr1 = new ArrayList<String>(Arrays.asList(str));
int [] indices = {3,1,2,0};
ArrayList<String> arr2 = new ArrayList(arr1.size());
for (int i = 0; i < arr1.size(); i++) {
arr2.add("0");
}
int arrIndex = 0;
for (int i : indices){
String st = arr1.get(arrIndex);
arr2.set(i, st);
arrIndex++;
}
System.out.println(arr1.toString());
System.out.println(arr2.toString());
}
}
For reusing same data, please see my solution:
public static void main(String[] args) {
String[] strs = new String[]{"a", "b", "c", "d"};
int[] indices = {3, 1, 2, 0};
String tmp;
for (int i = 0; i < strs.length; i++) {
if (i != indices[i]) {
tmp = strs[i];
strs[i] = strs[indices[i]];
strs[indices[i]] = tmp;
indices[indices[i]] = indices[i];
indices[i] = i;
}
}
for (int i : indices) {
System.out.print(i + " ");
}
System.out.println();
for (String str : strs) {
System.out.print(str + " ");
}
}
Output is:
0 1 2 3
d b c a
Alternate reorder in place based on cycles. Note that indices will be changed to {0,1,2,3}. I don't have Java installed (yet), so I converted working C++ code to what I think is proper Java syntax.
for (int i = 0; i < arr1.size(); i++) {
if(i != indices[i]) {
String st = arr1.get(i);
int t = indices[i];
int k = i;
int j;
while(i != (j = indices[k])){
arr1.set(k, arr1.get(j));
indices[k] = k;
k = j;
}
arr1.set(k, st);
indices[k] = k;
}
}
For this specific case {3,1,2,0}, all this does is swap 0 and 3. The longest cycle occurs when the indices are rotated, such as {3 0 1 2}, in which case st=arr1[0], arr1[0] = arr1[3], arr[3] = arr1[2], arr1[2] = arr1[1], arr1[1] = st.
There is a (a little bit) more simple solution:
int [] indices = {3,1,2,0};
ArrayList<String> arr2 = new ArrayList<String>();
for (int i = 0; i < arr1.size(); i++) {
arr2.add(arr1.get(indices[i]));
}
At the below, just use "indices" for a new array.
public class Sorting {
public static void main(String[] args) {
String [] str = new String[] {"a","b","c","d"};
int [] indices = {3,1,2,0};
String sorted [] = new String [str.length] ;
int i = 0;
for (String string : str) {
sorted[indices[i]] = string;
i++;
}
for (String string : sorted) {
System.out.print(string + " ");
}
}
}
prints: d b c a

Replacing digit words into digits

I am trying to replace all digit words zero-nine into their corresponding digits 0-9 in a string.
I have created the two arrays of digit words and digits and then trying for loop with a replace to change the sentence.
Not sure what i am doing wrong.
I'm referencing my getNoDigitWordString method.
import java.util.*;
public class StringProcessor {
private String noSpaces;
private String input, noVowels;
private String noDigitWords;
private int numOfWords = 0, uppercaseLetters = 0,
numOfDigits = 0, digitWords = 0;
private String [] wordDigits = {"zero","one", "two", "three","four",
"five", "six", "seven", "eight", "nine"};
private String [] digits = {"0", "1", "2", "3", "4",
"5", "6", "7", "8", "9"};
public StringProcessor()
{
input = "";
}
public StringProcessor(String s)
{
StringTokenizer str = new StringTokenizer(s);
numOfWords = str.countTokens();
for (int i = 0; i < s.length(); i++)
{
if (Character.isUpperCase(s.charAt(i)))
uppercaseLetters++;
}
for (int i = 0; i < s.length(); i++)
{
if (Character.isDigit(s.charAt(i)))
numOfDigits++;
}
String [] strSplit = s.split(" ");
for(int i = 0; i < strSplit.length; i++)
{
for (int j = 0; j < wordDigits.length; j++)
{
if (strSplit[i].equalsIgnoreCase(wordDigits[j]))
digitWords++;
}
}
noSpaces = s.replace(" ","");
noVowels = s.replaceAll("[aeiou]", "-");
for(int i = 0; i < 10; i++)
{
noDigitWords = s.replace("wordDigits[i]", "digits[i]");
}
}
public void setString(String s)
{
input = s;
}
public String getString()
{
return input;
}
public int wordCount()
{
return numOfWords;
}
public int uppercaseCount()
{
return uppercaseLetters;
}
public int digitCount()
{
return numOfDigits;
}
public int digitWordCount()
{
return digitWords;
}
public String getNoSpaceString()
{
return noSpaces;
}
public String getNoVowelString()
{
return noVowels;
}
public String getNoDigitWordString()
{
return noDigitWords;
}
public static void main(String[] args)
{
String input;
Scanner keyboard = new Scanner(System.in);
System.out.print("Enter a line of text: ");
input = keyboard.nextLine();
StringProcessor str = new StringProcessor(input);
System.out.println("words: " + str.wordCount());
System.out.println("uppercase: " + str.uppercaseCount());
System.out.println("digits: " + str.digitCount());
System.out.println("digit words " + str.digitWordCount());
System.out.println("line with no spaces: " + str.getNoSpaceString());
System.out.println("line with vowels replaced: " + str.getNoVowelString());
System.out.println("line with digit words replaced: " + str.getNoDigitWordString());
}
}
Thanks.
This is what you're looking for:
noDigitWords = s;
for(int i = 0; i < strSplit.length; i++)
{
for (int j = 0; j < wordDigits.length; j++)
{
if (strSplit[i].equalsIgnoreCase(wordDigits[j])){
noDigitWords = noDigitWords.replace(strSplit[i], digits[j]);
break;
}
}
}
Instead of this:
for(int i = 0; i < 10; i++)
{
noDigitWords = s.replace("wordDigits[i]", "digits[i]");
}
Aside from the problem #dcharms pointed out, this is not going to work:
for(int i = 0; i < 10; i++)
{
noDigitWords = s.replace(wordDigits[i], digits[i]);
}
Here's what happens: First, you search s for "zero", and call s.replace. This returns a string with the word "zero" replaced by "0". Then that string is assigned to noDigitWords. But s itself does not change.
Then, next time through the loop, you search in the original s for the next word. The work you did in the previous iteration, which was in noDigitWords, gets thrown away.
The result will be that the last word you search for, "nine", should get replaced. But any other replacements you've made will be thrown away.
Each time the following code calls the replace method, the string noDigitWords is overwritten.
for(int i = 0; i < 10; i++)
{
noDigitWords = s.replace("wordDigits[i]", "digits[i]");
}
After the final iteration of the loop, the string "one nine" becomes "one 9" rather than "1 9" as desired. The solution is to call the replace method on the return value of the previous iteration of the loop. Initialize the string noDigitWords to the value of the string s. Each iteration do the replace on noDigitWords as shown below.
noDigitWords = s;
for(int i = 0; i < 10; i++)
{
noDigitWords = noDigitWords.replace(wordDigits[i], digits[i]);
}
Try replacing noDigitWords = s.replace("wordDigits[i]", "digits[i]"); with noDigitWords = s; outside for loop and
noDigitWords = noDigitWords.replaceAll(wordDigits[i], digits[i]); inside.
Your original was looking for a string "wordDigits[i]" instead of the contents of wordDigits[i]. Your output had a similar issue.

Categories