does anyone know a faster way to convert string to int array?
Java V7
The format given is "4 343 234 -24" and so on. Spaces between the numbers, amount of numbers is known beforhand just as is the range within the numbers are
long[] array = new long[length];
for (int i = 0; i < length - 1; i++) {
array[i] = Integer.parseInt(n.substring(0, n.indexOf(' ')));
n = n.substring(n.substring(0, n.indexOf(' ')).length() + 1);
}
array[length - 1] = Integer.parseInt(n);
Using String.split() is by far the most efficient when you want to split by a single character (a space, in your case).
If you are aiming for maximal efficiency when splitting by spaces, then this would be a good solution:
List<Integer> res = new ArrayList<>();
Arrays.asList(kraft.split(" ")).forEach(s->res.add(Integer.parseInt(s)));
Integer[] result = res.toArray(new Integer[0]);
And this works for any number of numbers.
Splitting the input with the pattern \\s+ would handle one or more white-space characters, not only spaces, appearing between the numbers.
Stream.of(input.split("\\s+")).mapToInt(Integer::parseInt).toArray();
The mapToInt method returns an IntStream which provides the toArray method. This method returns an array containing the elements of the IntStream.
if You are using Java8 or higher version then you can get your expected output by writing this single line of code.
String str= "4 343 234 -24";
int[] intArr=Stream.of(str.split(" ")).mapToInt(Integer::parseInt).toArray();
System.out.println(Arrays.toString(intArr));
Related
I need to generate all palindromic numbers for a given number base (which should be able to be of size up to 10,000), in a given range. I need a efficient way to do it.
I stumbled upon this answer, which is related to base 10 directly. I'm trying to adapt it to work for "all" bases:
public static Set<String> allPalindromic(long limit, int base, char[] list) {
Set<String> result = new HashSet<String>();
for (long i = 0; i <= base-1 && i <= limit; i++) {
result.add(convert(i, base, list));
}
boolean cont = true;
for (long i = 1; cont; i++) {
StringBuffer rev = new StringBuffer("" + convert(i, base, list)).reverse();
cont = false;
for (char d : list) {
String n = "" + convert(i, base, list) + d + rev;
if (convertBack(n, base, list) <= limit) {
cont = true;
result.add(n);
}
}
}
return result;
}
convert() method converts a number to a string representation of that number in a given base using a list of chars for digits.
convertBack() converts back the string representation of a number to base 10.
When testing my method for base 10, it leaves out two-digit palindromes and then the next ones it leaves out are 1001,1111,1221... and so on.
I'm not sure why.
Here are the conversion methods if needed.
Turns out, this gets slower with my other code because of constant conversions since I need the all numbers in order and in decimal. I'll just stick to iterating over every integer and converting it to every base and then checking if its a palindrome.
I don't have enough reputation to comment, but if you are only missing even length palindromes, then most probably there is something wrong with your list. Most probably you have forgot to add an empty entry in list as to generate 1001, it should be like num(10) + empty("") + rev(01).
There is no so many appropriate chars for digits in all possible bases (like 0xDEADBEEF for hex, and I suppose that convert has some limit like 36), so forget about exotic digits, and use simple lists or arrays like [8888, 123, 5583] for digits in 10000-base.
Then convert limit into need base, store it.
Now generate symmetric arrays of odd and even length like
[175, 2, 175] or [13, 221, 221, 13]. If length is the same as limit length, compare array values and reject too high numbers.
You can also use limit array as starting and generate only palindromes with lesser values.
so I'm pretty new at Java and StackOverflow (That's what they all say) and I am stuck at the given problem:
My method is given a String e.g.: "[ 25 , 25 , 125 , 125]". Now the method should return an Array of integers representation of the String provided, that is: it should return
[25,25,125,125].
Here is a segment of my method. Note: input is the String provided
if(input.charAt(index) == '['){
index++;
int start = index;
while(index <= input.length() && input.charAt(index) != ']'){
index++;
}
String[] arrayStr = input.substring(start, index).split(",");
int[] arrayInt = new int[4];
for (int i = 0; i < arrayStr.length; i++){
arrayInt[i] = Integer.parseInt(arrayStr[i]);
}
return arrayInt;
My code works if input is: "[25,25,125,125]" (If there are no spaces between the numbers).
However if there are spaces between the numbers then my code doesn't work and I understand why, but I am struggling to find a way to solve this problem. Any help will be appreciated.
Spaces will fail with Integer.parseInt(arrayStr[i]) (e.g. the string "25 " is not a valid number as it contains a space. (parseInt will throw an exception in such cases.)
However you can solve it quickly by trimming your array elements:
Integer.parseInt(arrayStr[i].trim())
trim() returns a copy of the string without leading/trailing white space
You can replace the space with empty in the string
input=input.replace(" ","")
You can
remove [ and ] and all spaces
split on , to get all tokens
iterate over all tokens
parse string number to int
add parsed int to result array
So your code can look like
String data = "[ 25 , 25 , 125 , 125]";
String[] tokens = data.replaceAll("\\[|\\]|\\s", "").split(",");
int[] array = new int[tokens.length];
for (int i=0; i<tokens.length; i++){
array[i]=Integer.parseInt(tokens[i]);
}
Or if you have Java 8 you can use streams like
int[] array = Stream.of(data.replaceAll("\\[|\\]|\\s", "").split(","))
.mapToInt(number -> Integer.parseInt(number))
.toArray();
I want to export pattern of bit stream in a String varilable. Assume our bit stream is something like bitStream="111000001010000100001111". I am looking for a Java code to save this bit stream in a specific array (assume bitArray) in a way that all continous "0"s or "1"s be saved in one array element. In this example output would be somethins like this:
bitArray[0]="111"
bitArray[1]="00000"
bitArray[2]="1"
bitArray[3]="0"
bitArray[4]="1"
bitArray[5]="0000"
bitArray[6]="1"
bitArray[7]="0000"
bitArray[8]="1111"
I want to using bitArray to calculate the number of bit which is stored in each continous stream. For example in this case the final output would be, "3,5,1,1,1,4,1,4,4". I figure it out that probably "split" method would solve this for me. But I dont know what splitting pattern would do that for me, if i Using bitStream.split("1+") it would split on contious "1" pattern, if i using bitStream.split("0+") it will do that base on continous"0" but how it could be based on both?
Mathew suggested this solution and it works:
var wholeString = "111000001010000100001111";
wholeString = wholeString.replace('10', '1,0');
wholeString = wholeString.replace('01', '0,1');
stringSplit = wholeString.split(',');
My question is "Is this solution the most efficient one?"
Try replacing any occurrence of "01" and "10" with "0,1" and "1,0" respectively. Then once you've injected the commas, split the string using the comma as the delimiting character.
String wholeString = "111000001010000100001111"
wholeString = wholeString.replace("10", "1,0");
wholeString = wholeString.replace("01", "0,1");
String stringSplit[] = wholeString.split(",");
You can do this with a simple regular expression. It matches 1s and 0s and will return each in the order they occur in the stream. How you store or manipulate the results is up to you. Here is some example code.
String testString = "111000001010000100001111";
Pattern pattern = Pattern.compile("1+|0+");
Matcher matcher = pattern.matcher(testString);
while (matcher.find())
{
System.out.print(matcher.group().length());
System.out.print(" ");
}
This will result in the following output:
3 5 1 1 1 4 1 4 4
One option for storing the results is to put them in an ArrayList<Integer>
Since the OP wanted most efficient, I did some tests to see how long each answer takes to iterate over a large stream 10000 times and came up with the following results. In each test the times were different but the order of fastest to slowest remained the same. I know tick performance testing has it's issues like not accounting for system load but I just wanted a quick test.
My answer completed in 1145 ms
Alessio's answer completed in 1202 ms
Matthew Lee Keith's answer completed in 2002 ms
Evgeniy Dorofeev's answer completed in 2556 ms
Hope this helps
I won't give you a code, but I'll guide you to a possible solution:
Construct an ArrayList<Integer>, iterate on the array of bits, as long as you have 1's, increment a counter and as soon as you have 0, add the counter to the ArrayList. After this procedure, you'll have an ArrayList that contain numbers, etc: [1,2,2,3,4] - Representing a serieses of 1's and 0's.
This will represent the sequences of 1's and 0's. Then you construct an array of the size of the ArrayList, and fill it accordingly.
The time complexity is O(n) because you need to iterate on the array only once.
This code works for any String and patterns, not only 1s and 0s. Iterate char by char, and if the current char is equal to the previous one, append the last char to the last element of the List, otherwise create a new element in the list.
public List<String> getArray(String input){
List<String> output = new ArrayList<String>();
if(input==null || input.length==0) return output;
int count = 0;
char [] inputA = input.toCharArray();
output.add(inputA[0]+"");
for(int i = 1; i <inputA.length;i++){
if(inputA[i]==inputA[i-1]){
String current = output.get(count)+inputA[i];
output.remove(count);
output.add(current);
}
else{
output.add(inputA[i]+"");
count++;
}
}
return output;
}
try this
String[] a = s.replaceAll("(.)(?!\\1)", "$1,").split(",");
I tried to implement #Maroun Maroun solution.
public static void main(String args[]){
long start = System.currentTimeMillis();
String bitStream ="0111000001010000100001111";
int length = bitStream.length();
char base = bitStream.charAt(0);
ArrayList<Integer> counts = new ArrayList<Integer>();
int count = -1;
char currChar = ' ';
for (int i=0;i<length;i++){
currChar = bitStream.charAt(i);
if (currChar == base){
count++;
}else {
base = currChar;
counts.add(count+1);
count = 0;
}
}
counts.add(count+1);
System.out.println("Time taken :" + (System.currentTimeMillis()-start ) +"ms");
System.out.println(counts.toString());
}
I believe it is more effecient way, as he said it is O(n) , you are iterating only once. Since the goal to get the count only not to store it as array. i woul recommen this. Even if we use Regular Expression ( internal it would have to iterate any way )
Result out put is
Time taken :0ms
[1, 3, 5, 1, 1, 1, 4, 1, 4, 4]
Try this one:
String[] parts = input.split("(?<=1)(?=0)|(?<=0)(?=1)");
See in action here: http://rubular.com/r/qyyfHNAo0T
hello every one i got a string from csv file like this
LECT-3A,instr01,Instructor 01,teacher,instr1#learnet.com,,,,male,phone,,
how to split this string with comma i want the array like this
s[0]=LECT-3A,s[1]=instr01,s[2]=Instructor 01,s[3]=teacher,s[4]=instr1#learnet.com,s[5]=,s[6]=,s[7]=,s[8]=male,s[9]=phone,s[10]=,s[11]=
can anyone please help me how to split the above string as my array
thank u inadvance
- Use the split() function with , as delimeter to do this.
Eg:
String s = "Hello,this,is,vivek";
String[] arr = s.split(",");
you can use the limit parameter to do this:
The limit parameter controls the number of times the pattern is applied and therefore affects the length of the resulting array. If the limit n is greater than zero then the pattern will be applied at most n - 1 times, the array's length will be no greater than n, and the array's last entry will contain all input beyond the last matched delimiter. If n is non-positive then the pattern will be applied as many times as possible and the array can have any length. If n is zero then the pattern will be applied as many times as possible, the array can have any length, and trailing empty strings will be discarded.
Example:
String[]
ls_test = "LECT-3A,instr01,Instructor 01,teacher,instr1#learnet.com,,,,male,phone,,".split(",",12);
int cont = 0;
for (String ls_pieces : ls_test)
System.out.println("s["+(cont++)+"]"+ls_pieces);
output:
s[0]LECT-3A
s[1]instr01
s[2]Instructor 01
s[3]teacher
s[4]instr1#learnet.com
s[5]
s[6]
s[7]
s[8]male
s[9]phone
s[10]
s[11]
You could try something like so:
String str = "LECT-3A,instr01,Instructor 01,teacher,instr1#learnet.com,,,,male,phone,,";
List<String> words = new ArrayList<String>();
int current = 0;
int previous = 0;
while((current = str.indexOf(",", previous)) != -1)
{
words.add(str.substring(previous, current));
previous = current + 1;
}
String[] w = words.toArray(new String[words.size()]);
for(String section : w)
{
System.out.println(section);
}
This yields:
LECT-3A
instr01
Instructor 01
teacher
instr1#learnet.com
male
phone
I would like some guidance on how to split a string into N number of separate strings based on a arithmetical operation; for example string.length()/300.
I am aware of ways to do it with delimiters such as
testString.split(",");
but how does one uses greedy/reluctant/possessive quantifiers with the split method?
Update: As per request a similar example of what am looking to achieve;
String X = "32028783836295C75546F7272656E745C756E742E657865000032002E002E005C0"
Resulting in X/3 (more or less... done by hand)
X[0] = 32028783836295C75546F
X[1] = 6E745C756E742E6578650
x[2] = 65000032002E002E005C0
Dont worry about explaining how to put it into the array, I have no problem with that, only on how to split without using a delimiter, but an arithmetic operation
You could do that by splitting on (?<=\G.{5}) whereby the string aaaaabbbbbccccceeeeefff would be split into the following parts:
aaaaa
bbbbb
ccccc
eeeee
fff
The \G matches the (zero-width) position where the previous match occurred. Initially, \G starts at the beginning of the string. Note that by default the . meta char does not match line breaks, so if you want it to match every character, enable DOT-ALL: (?s)(?<=\G.{5}).
A demo:
class Main {
public static void main(String[] args) {
int N = 5;
String text = "aaaaabbbbbccccceeeeefff";
String[] tokens = text.split("(?<=\\G.{" + N + "})");
for(String t : tokens) {
System.out.println(t);
}
}
}
which can be tested online here: http://ideone.com/q6dVB
EDIT
Since you asked for documentation on regex, here are the specific tutorials for the topics the suggested regex contains:
\G, see: http://www.regular-expressions.info/continue.html
(?<=...), see: http://www.regular-expressions.info/lookaround.html
{...}, see: http://www.regular-expressions.info/repeat.html
If there's a fixed length that you want each String to be, you can use Guava's Splitter:
int length = string.length() / 300;
Iterable<String> splitStrings = Splitter.fixedLength(length).split(string);
Each String in splitStrings with the possible exception of the last will have a length of length. The last may have a length between 1 and length.
Note that unlike String.split, which first builds an ArrayList<String> and then uses toArray() on that to produce the final String[] result, Guava's Splitter is lazy and doesn't do anything with the input string when split is called. The actual splitting and returning of strings is done as you iterate through the resulting Iterable. This allows you to just iterate over the results without allocating a data structure and storing them all or to copy them into any kind of Collection you want without going through the intermediate ArrayList and String[]. Depending on what you want to do with the results, this can be considerably more efficient. It's also much more clear what you're doing than with a regex.
How about plain old String.substring? It's memory friendly (as it reuses the original char array).
well, I think this is probably as efficient a way to do this as any other.
int N=300;
int sublen = testString.length()/N;
String[] subs = new String[N];
for(int i=0; i<testString.length(); i+=sublen){
subs[i] = testString.substring(i,i+sublen);
}
You can do it faster if you need the items as a char[] array rather as individual Strings - depending on how you need to use the results - e.g. using testString.toCharArray()
Dunno, you'll probably need a method that takes string and int times and returns a list of strings. Pseudo code (haven't checked if it works or not):
public String[] splintInto(String splitString, int parts)
{
int dlength = splitString.length/parts
ArrayList<String> retVal = new ArrayList<String>()
for(i=0; i<splitString.length;i+=dlength)
{
retVal.add(splitString.substring(i,i+dlength)
}
return retVal.toArray()
}