Java Write to File Perfomance - java

i am trying to write to file with redirection from command line.
my programm is very slow when i read a file of 25MB and 90% of execution time spent in "System.out.println" .I tried some other methods than System.out.print but coulnt fix..
which method i have to use to print a big ArrayList? (with redirection)
i would appreciate your help and an example
thanks
here is my code:
public class Ask0 {
public static void main(String args[]) throws IOException {
int i = 0, token0, token1;
String[] tokens;
List<String> inputList = new ArrayList<>();
Map<Integer, List<Integer>> map = new HashMap<>();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String input;
while ((input = br.readLine()) != null) {
tokens = input.split("\\|");
inputList.add(tokens[0] + "|" + tokens[1]);
token0 = Integer.parseInt(tokens[0]);
token1 = Integer.parseInt(tokens[1]);
List<Integer> l = map.get(token0);
if (l == null) {
l = new ArrayList<>();
map.put(token0, l);
}
if (l.contains(token1) == false) {
l.add(token1);
}
i++;
}
i = 0;
for (int j = inputList.size(); j > 0; j--) {
tokens = inputList.get(i).split("\\|");
token0 = Integer.parseInt(tokens[0]);
token1 = Integer.parseInt(tokens[1]);
List l = map.get(token0);
System.out.println(tokens[0] + "|" + tokens[1] + "["
+ (l.indexOf(token1) + 1) + "," + l.size() + "]");
i++;
}
}
}
Input
3|78 4|7765 3|82 2|8 4|14 3|78 2|8 4|12
Desired result
3|78[1,2] 4|7765[1,3] 3|82[2,2] 2|8[1,1] 4|14[2,3] 3|78[1,2] 2|8[1,1] 4|12[3,3]

For speed, the below code:
Uses a StringBuilder for fast concatenation into a resulting String and fast output since only one massive String is printed at the end, saving unnecessary buffer flushes.
Doesn't create a bunch of Strings when parsing the input, just a small byte[] and Integers in an ArrayList.
Manually uses a 64kiB buffer for reading.
Doesn't rejoin the tokens with "|" in the middle only to split them again later.
Uses a HashMap<Integer, HashMap<Integer, Integer>> instead of a HashMap<Integer, ArrayList<Integer>> to save time on element lookups in the list (turns algorithm from O(n2) time to O(n) time).
Some speedups that might not work as you want:
Doesn't waste time properly handling Unicode.
Doesn't waste time properly handling negative or overflowed numbers.
Doesn't care what the separator characters are (you could input "1,2,3,4,5,6" instead and it would still work just like "1|2\n3|4\n5|6\n").
You can see that it gives the correct results for your test input here (except that it separates the outputs by newlines like in your code).
private static final int BUFFER_SIZE = 65536;
private static enum InputState { START, MIDDLE }
public static void main(final String[] args) throws IOException {
// Input the numbers
final byte[] inputBuffer = new byte[BUFFER_SIZE];
final List<Integer> inputs = new ArrayList<>();
int inputValue = 0;
InputState inputState = InputState.START;
while (true) {
int j = 0;
final int bytesRead = System.in.read(inputBuffer, 0, BUFFER_SIZE);
if (bytesRead == -1) {
if (inputState == InputState.MIDDLE) {
inputs.add(inputValue);
}
break;
}
for (int i = 0; i < bytesRead; i++) {
byte ch = inputBuffer[i];
int leftToken = 0;
if (ch < 48 || ch > 57) {
if (inputState == InputState.MIDDLE) {
inputs.add(inputValue);
inputState = InputState.START;
}
}
else {
if (inputState == InputState.START) {
inputValue = ch - 48;
inputState = InputState.MIDDLE;
}
else {
inputValue = 10*inputValue + ch - 48;
}
}
}
}
System.in.close();
// Put the numbers into a map
final Map<Integer, Map<Integer, Integer>> map = new HashMap<>();
for (int i = 0; i < inputs.size();) {
final Integer left = inputs.get(i++);
final Integer right = inputs.get(i++);
final Map<Integer, Integer> rights;
if (map.containsKey(left)) {
rights = map.get(left);
}
else {
rights = new HashMap<>();
map.put(left, rights);
}
rights.putIfAbsent(right, rights.size() + 1);
}
// Prepare StringBuilder with results
final StringBuilder results = new StringBuilder();
for (int i = 0; i < inputs.size();) {
final Integer left = inputs.get(i++);
final Integer right = inputs.get(i++);
final Map<Integer, Integer> rights = map.get(left);
results.append(left).append('|').append(right);
results.append('[').append(rights.get(right)).append(',');
results.append(rights.size()).append(']').append('\n');
}
System.out.print(results);
}
You can alternatively manually use a 64 kiB byte[] output buffer with System.out.write(outputBuffer, 0, bytesToWrite); System.out.flush(); as well if you want to save memory, though that's a lot more work.
Also, if you know the minimum and maximum values that you'll see, you can use int[] or int[][] arrays instead of Map<Integer, Integer> or Map<Integer, Map<Integer, Integer>>, though that's somewhat more involved as well. It would be very fast, though.

Related

Sort by number of apearances

for example, I am given a word and I have to sort its letters by the number of occurrences in that word, if 2 letters appear the same number of times it will be sorted by the lexicographic minimum.
For now, I have started to see how many times a letter appears in a word but from here I do not know exactly how to do it.
The problem requires me to use BufferedReader and BufferedWriter.
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Map<Character, Integer> m = new HashMap<>();
String s = sc.nextLine();
for (int i = 0; i < s.length(); ++i) {
char c = s.charAt(i);
if (m.containsKey(c))
m.put(c, m.get(c) + 1);
else
m.put(c, 1);
}
for (char letter = 'a'; letter <= 'z'; ++letter)
if (m.containsKey(letter))
System.out.println(letter + ": " + m.get(letter));
}
For the moment I am posting what letters appear most often in the word, but I do not know how to sort them by the number of occurrences and in case there are two letters that appear at the same number of times with the minimum lexicographic.
I hope this is what you want
public static void main(String[] args) {
Map<Character, Integer> m = new HashMap<>();
String testString = "Instructions";
Map<Character, List<Character>> map = new HashMap<>();
for (int i = 0; i < testString.length(); i++) {
char someChar = testString.charAt(i);
if (someChar == ' ') {
continue;
}
char ch = testString.charAt(i);
List<Character> characters = map.getOrDefault(Character.toLowerCase(ch), new ArrayList<>());
characters.add(ch);
map.put(Character.toLowerCase(ch), characters);
}
List<Map.Entry<Character, List<Character>>> list = new ArrayList<>(map.entrySet());
list.sort((o1, o2) -> {
if (o1.getValue().size() == o2.getValue().size()) {
return o1.getKey() - o2.getKey();/// your lexicographic comparing
}
return o2.getValue().size() - o1.getValue().size();
});
list.forEach(entry -> entry.getValue().forEach(System.out::print));
}
To count letters in word, you can use much simpler method:
define array with 26 zeros, scan input line and increase appropriate index in this array, so if you meet 'a' (or 'A' - which is the same letter, but different symbol) - you will increase value at index 0, b - index 1, etc
during this scan you can also compute most occurred symbol, like this:
public static void main(final String[] args) throws IOException {
char maxSymbol = 0;
int maxCount = 0;
final int[] counts = new int[26]; // number of times each letter (a-z) appears in string
try (final BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {
final String s = br.readLine().toLowerCase(); // calculate case-insensitive counts
for (final char c : s.toCharArray()) {
final int idx = c - 'a'; // convert form ASCII code to 0-based index
counts[idx]++;
if (counts[idx] > maxCount) {
maxSymbol = c; // we found most occurred symbol for the current moment
maxCount = counts[idx];
} else if (counts[idx] == maxCount) { // we found 2nd most occurred symbol for the current moment, need to check which one is minimal in lexicographical order
if (c < maxSymbol) {
maxSymbol = c;
}
}
}
}
if (maxSymbol > 0) {
System.out.println("Most frequent symbol " + maxSymbol + " occurred " + maxCount);
}
}
I've used buffered reader to get data from stdin, but I have no idea where to put buffered writer here, maybe to print result?

Counting the number of each character in a file

I'm reading the contents of a text file char by char, then I've sorted them in ascending order and count the number of times each char occurs. When I run the program my numbers are way off, for example there are 7 'A' in the file, but I get 17. I'm thinking this means either something is wrong with my counting, or the way I'm reading the chars. Any ideas on what is wrong?
public class CharacterCounts {
public static void main(String[] args) throws IOException{
String fileName = args[0];
BufferedReader in = new BufferedReader(new FileReader(new File(fileName)));
ArrayList<Character> vals = new ArrayList<Character>();
ArrayList<Integer> valCounts = new ArrayList<Integer>();
while(in.read() != -1){
vals.add((char)in.read());
}
Collections.sort(vals);
//This counts how many times each char occures,
//resets count to 0 upon finding a new char.
int count = 0;
for(int i = 1; i < vals.size(); i++){
if(vals.get(i - 1) == vals.get(i)){
count++;
} else {
valCounts.add(count + 1);
count = 0;
}
}
//Removes duplicates from vals by moving from set then back to ArrayList
Set<Character> hs = new HashSet<Character>();
hs.addAll(vals);
vals.clear();
vals.addAll(hs);
//System.out.print(vals.size() + "," + valCounts.size());
for(int i = 0; i < vals.size(); i++){
//System.out.println(vals.get(i));
System.out.printf("'%c' %d\n", vals.get(i), valCounts.get(i));
}
}
}
When you write
if(vals.get(i - 1) == vals.get(i)){
Both are completely different references and they are not at all equals. You have to compare their value.
You want
if(vals.get(i - 1).equals(vals.get(i))){
I think you are overcomplicating your count logic. In addition you call read() twice in the loop so you are skipping every other value.
int[] counts = new int[256]; // for each byte value
int i;
while ((i = in.read()) != -1) { // Note you should only be calling read once for each value
counts[i]++;
}
System.out.println(counts['a']);
Why not use regex instead, the code will be more flexible and simple. Have a look at the code below:
...
final BufferedReader reader = new BufferedReader(new FileReader(filename));
final StringBuilder contents = new StringBuilder();
//read content in a string builder
while(reader.ready()) {
contents.append(reader.readLine());
}
reader.close();
Map<Character,Integer> report = new TreeMap<>();
//init a counter
int count = 0;
//Iterate the chars from 'a' to 'z'
for(char a = 'a';a <'z'; a++ ){
String c = Character.toString(a);
//skip not printable char
if(c.matches("\\W"))
continue;
String C = c.toUpperCase();
//match uppercase and lowercase char
Pattern pattern = Pattern.compile("[" + c + C +"]", Pattern.MULTILINE);
Matcher m = pattern.matcher(contents.toString());
while(m.find()){
count++;
}
if(count>0){
report.put(a, count);
}
//reset the counter
count=0;
}
System.out.println(report);
...

Arranging word to formpalindrome

Hello i´ve been trying to form palindromes from this input:
String[] text ={"ivcci", "oyotta", "cecarar","bbb","babbbb"};
getPalindrome(text);
and i need to rearrange all words in array to produce this output
civic
-1
rececar
bbb
bbabb
the method expects to receive an array of Strings like
public static String getPalindrome(String[] text){}
"returning -1 means i.g "oyotta" in array can´t form a palíndrome
i´ve been testing this code and it works but i.g "cecarar" is not producing "racecar", as im a bit new in java i used an String intead an array of Strings, can anybody help to write this code properly please?
Thanks a lot!
public static String getPalindrome(String s) {
if (s == null)
return null;
Map<Character, Integer> letters = new HashMap<Character, Integer>();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (!letters.containsKey(c))
letters.put(c, 1);
else
letters.put(c, letters.get(c) + 1);
}
char[] result = new char[s.length()];
int i = 0, j = result.length - 1;
Character middle = null;
for (Entry<Character, Integer> e : letters.entrySet()) {
int val = e.getValue();
char c = e.getKey();
if (val % 2 != 0) {
if (middle == null && s.length() % 2 != 0) {
middle = c;
val--;
} else
return "-1";
}
for (int k = 0; k < val / 2; k++) {
result[i++] = c;
result[j--] = c;
}
}
if (middle != null)
result[result.length / 2] = middle;
return new String(result);
}
In order for a set of characters to be able to produce a palindrome, only one of the letters can be repeated an odd number of times, so you can first weed that out.
Without writing actual code for you, here is the algorithm I would use:
Create a map of characters to a counter. Possible to do int[] counts = new int[26];
Go through each character in the input string, and increment the count: ++counts[Character.toLower(c)-'a'];
Then go through each character, and see if its odd if (counts[i] & 1 != 0) { if (oddIndex != -1) { return -1; } oddIndex=i; } This will return -1 if there is two or more odd counts.
Then, you can create a StringBuilder, and start with the oddIndex in the middle, if it exists.
Then go through the counts, and add count[i]/2 to the front and back of your string builder.
That'll give you a symmetric string from the original inputs.
Now, if you actually need words, then you'll have to have a dictionary of palindromes. You can actually preprocess all the palindromes to have a map of "sorted character string"=>"palindrome"
class PalindromeChecker
{
final Map<String, String> palindromes = new HashMap<String, String>();
public PalindromeChecker(Iterable<String> allPalindromes) {
for (String palindrome: allPalindromes) {
char[] chars = palindrome.getChars();
Arrays.sort(chars);
palindromes.put(String.valueOf(chars), palindromes);
}
}
public String getPalindrome(String input) {
char[] chars = input.getChars();
Arrays.sort(chars);
return palindromes.get(String.valueOf(chars));
}
}
As other users pointed out, a string can be rearranged as a palindrome only if there is at most one character that appears an odd number of times.
Once you have confirmed that a string can be converted to a palindrome, you can construct the palindrome as follows (this is just one of many methods of course):
place at the sides of the string all the pairs of characters that you can get
place at the middle of the string the single character that is left out, in case there is such a character.
Example:
public class Palindromes {
public static void main(String[] args) {
String[] text = {"ivcci", "oyotta", "cecarar","bbb","babbbb"};
for(String str : text){
evaluatePalindrome(str);
}
}
private static void evaluatePalindrome(String str){
PalindromeCandidate pc = new PalindromeCandidate(str);
if(pc.isPalindrome()){
System.out.println(pc.getPalindrome());
} else {
System.out.println("-1");
}
}
}
public class PalindromeCandidate {
private final CharacterCount characterCount;
public PalindromeCandidate(String originalString) {
this.characterCount = new CharacterCount(originalString);
}
public boolean isPalindrome(){
Collection<Integer> counts = characterCount.asMap().values();
int oddCountOccurrences = 0;
for(Integer count : counts){
oddCountOccurrences += (count%2);
}
return (oddCountOccurrences <= 1);
}
public String getPalindrome(){
if(!isPalindrome()){
throw new RuntimeException("Cannot be rearranged as a palindrome.");
}
Map<Character, Integer> counts = characterCount.asMap();
StringBuilder leftSide = new StringBuilder();
StringBuilder middle = new StringBuilder();
for(Character ch : counts.keySet()){
int occurrences = counts.get(ch);
while(occurrences > 1){
leftSide.append(ch);
occurrences -= 2;
}
if(occurrences > 0){
middle.append(ch);
}
}
StringBuilder rightSide = new StringBuilder(leftSide).reverse();
return leftSide.append(middle).append(rightSide).toString();
}
}
/**
* Thin wrapper around a Map<Character, Integer>. Used for counting occurences
* of characters.
*/
public class CharacterCount {
private final Map<Character, Integer> map;
public CharacterCount(String str) {
this.map = new HashMap<>();
for(Character ch : str.toCharArray()){
increment(ch);
}
}
private void increment(Character ch){
this.map.put(ch, getCount(ch) + 1);
}
private Integer getCount(Character ch){
if(map.containsKey(ch)){
return map.get(ch);
} else {
return 0;
}
}
public Map<Character, Integer> asMap(){
return new HashMap<>(map);
}
}

How can i keep track of multiple counter variables

I have written some code that count the number of "if" statements from unknown number of files. How can i keep a count for each file separate and a total of "if" from all files?
code:
import java.io.*;
public class ifCounter4
{
public static void main(String[] args) throws IOException
{
// variable to keep track of number of if's
int ifCount = 0;
for (int c = 0; c < args.length; c++)
{
// parameter the TA will pass in
String fileName = args[c];
// create a new BufferReader
BufferedReader reader = new BufferedReader( new FileReader (fileName));
String line = null;
StringBuilder stringBuilder = new StringBuilder();
String ls = System.getProperty("line.separator");
// read from the text file
while (( line = reader.readLine()) != null)
{
stringBuilder.append(line);
stringBuilder.append(ls);
}
// create a new string with stringBuilder data
String tempString = stringBuilder.toString();
// create one last string to look for our valid if(s) in
// with ALL whitespace removed
String compareString = tempString.replaceAll("\\s","");
// check for valid if(s)
for (int i = 0; i < compareString.length(); i++)
{
if (compareString.charAt(i) == ';' || compareString.charAt(i) == '}' || compareString.charAt(i) == '{') // added opening "{" for nested ifs :)
{
i++;
if (compareString.charAt(i) == 'i')
{
i++;
if (compareString.charAt(i) == 'f')
{
i++;
if (compareString.charAt(i) == '(')
ifCount++;
} // end if
} // end if
} // end if
} // end for
// print the number of valid "if(s) with a new line after"
System.out.println(ifCount + " " + args[c]); // <-- this keeps running total
// but not count for each file
}
System.out.println();
} // end main
} // end class
You can create a Map that stores the file names as keys and the count as values.
Map<String, Integer> count = new HashMap<String, Integer>();
After each file,
count.put(filename, ifCount);
ifcount = 0;
Walk the value set to get the total.
How about a Map which uses the file name as key and keeps the count of ifs as value? For overall count, store it in its own int, or just calculate it when needed by adding up all the values in the Map.
Map<String, Integer> ifsByFileName = new HashMap<String, Integer>();
int totalIfs = 0;
for each if in "file" {
totalIfs++;
Integer currentCount = ifsByFileName.get(file);
if (currentCount == null) {
currentCount = 0;
}
ifsByFileName.put(file, currentCount + 1);
}
// total from the map:
int totalIfsFromMap = 0;
for (Integer fileCount : ifsByFileName.values()) {
totalIfsFromMap += fileCount;
}
Using an array would solve this problem.
int[] ifCount = new int[args.length];
and then in your loop ifCount[c]++;
Problematic in this scenario is when many threads want to increase the same set of counters.
Operations such as ifCount[c]++; and ifsByFileName.put(file, currentCount + 1);are not thread safe.
The obvious solution to use a ConcurrentMap and AtomicLong is also insufficient, since you must place the initial values of 0, which would require additional locking.
The Google Guava project provides a convenient out of the box sollution: AtomicLongMap
With this class you can write:
AtomicLongMap<String> cnts = AtomicLongMap.create();
cnts.incrementAndGet("foo");
cnts.incrementAndGet("bar");
cnts.incrementAndGet("foo");
for (Entry<String, Long> entry : cnts.asMap().entrySet()) {
System.out.println(entry);
}
which prints:
foo=2
bar=1
And is completely thread safe.
This is a counter that adds to 100 and if you edit the value of N it puts a * next to the multiples of.
public class SmashtonCounter_multiples {
public static void main(String[] args) {
int count;
int n = 3; //change this variable for different multiples of
for(count = 1; count <= 100; count++) {
if((count % n) == 0) {
System.out.print(count + "*");
}
else {
System.out.print(count);
if (count < 100) {
System.out.print(",");
}
}
}
}

To add commas in file

This is my first question in this forum...
I have a file with numerous data fields (both numeric and characters) in the file.
I want to delimit the file with set of delimiter length like 2,5,1,9,6 etc.
(Alternatively: I have a list of field lengths such as 2,5,1,9,6, and I want to insert comma delimiters in (a copy of) the source string after each field.)
For example, if my file is like this:
9483trdcvge245621jde
then I need to insert commas at 2,5,1,9,6 etc.
and the output will be:
94,83trd,c,vge245621,jde,
I need to do this in JAVA
Please help me to solve this issue.
Thanks in advance
if (myString.equals("9483trdcvge245621jde")) {
myString = "94,83trd,c,vge245621,jde";
}
Jokingly ;-)
I think something like this...
private static final int[] pos = {2, 5, 1, 9, 6};
private static final String DIV = ",";
public static String parse(String str) {
int start = 0;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < pos.length; i++) {
if (i > 0) {
sb.append(DIV);
}
int end = start + pos[i];
if (end <= str.length()) {
sb.append(str.substring(start, end));
start = end;
} else {
sb.append(str.substring(start));
}
}
return sb.toString();
}
Read in the file as a StringBuilder then use something like this
StringBuilder sb = new StringBuilder(file); //The string builder
while (/*the string builder isn't finished*/)
{
int position = ;//The position you want the comma at 2 or 4 or whatever
sb.insert(position, ",");
}
Loop through as many times as needed.
I think i would do it this way
str being the input string
pos being the lengths of the parts after which we should put a comma
Code:
public static String partition(String str, int[] pos) {
int oldPos = 0;
StringBuilder builder = new StringBuilder(str.length() + pos.length);
for(int len : pos) {
builder.append(str.substring(oldPos, oldPos+len)).append(',');
oldPos += len;
}
builder.append(str.substring(oldPos)).append(',');
return builder.toString();
}
I think I don’t understand the question. Read the file, line by line, and insert commas into the string.
String newString = line.substring(0, firstComma) + "," + line.substring(firstComma + 1);
Of course this is terribly inefficient and can be optimized in numerous ways.
Assuming you have all these as Strings you can use String.substring(start, end). Then simply append + the substrings and commas together.
String data = "9483trdcvge245621jde";
String result = "";
result += data.substring(0,2) + ",";
result += data.substring(2, 7) + ",";
result += data.substring(7, 8) + ",";
etc...
Note: Using + to append string like this is very slow as it reallocates and moves data around each time. There are faster ways to concatenate Strings if speed is an issue.
String newString = "";
int[] positions = { 2, 5, 1, 9, 6 }; //etc
for (int i = 0; i > positions.length; i++) {
String tempString = "";
if (i == positions.length) { //for the last item
tempString = oldString.substring(0, positions[i]);
}
else { //every item except the last item
tempString = oldString.substring(0, positions[i]) + ",";
}
oldString = oldString.substring(positions[i]);
newString += tempString;
}
Stored the positions in an array. Iterate through, adding the delimited strings to a new string and removing them from the old one.
This might not be the best way, but its how I would do it. :P
Here's one solution:
package com.foo;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class Commafy {
public static final String SEPARATOR = ",";
private static void fail(String message) {
System.err.println(message);
System.exit(1);
}
private static int[] argsAsInts(String[] args) {
if (args.length < 2) {
fail("argument list of file name followed by field lengths is required");
}
int[] result = new int[args.length - 1];
for (int i = 1; i < args.length; ++i) {
try {
result[i - 1] = Integer.parseInt(args[i]);
} catch (NumberFormatException nfe) {
fail("can't convert argument \"" + args[i] + "\" to integer");
}
}
return result;
}
private static int[] partialSums(int[] lengths) {
int[] result = new int[lengths.length];
int start = 0;
for (int i = 0; i < lengths.length; ++i) {
result[i] = start;
start += lengths[i];
}
return result;
}
private static int[] fieldsEndAt(int[] lengths, int[] starts) {
int[] result = new int[lengths.length];
for (int i = 0; i < lengths.length; ++i) {
result[i] = starts[i] + lengths[i];
}
return result;
}
private static void process(
String fileName, int[] starts, int[] ends
) throws IOException {
BufferedReader br = new BufferedReader(
new FileReader(fileName)
);
final int MIN_LENGTH = ends[ends.length - 1];
String line = br.readLine();
while (line != null) {
if (line.length() < MIN_LENGTH) {
System.err.println("short input line \"" + line +"\" skipped");
} else {
StringBuilder sb = new StringBuilder();
String separate = "";
for (int i = 0; i < starts.length; ++i) {
sb.append(separate).append(line.substring(starts[i], ends[i]));
separate = SEPARATOR;
}
System.out.println(sb.toString());
}
line = br.readLine();
}
br.close();
}
public static void main(String[] args) {
int[] lengths = argsAsInts(args);
int[] starts = partialSums(lengths);
int[] ends = fieldsEndAt(lengths, starts);
try {
process(args[0], starts, ends);
} catch (IOException e) {
fail("I/O Exception while processing input");
}
}
}
Given a data file named data/fixedlengthdata.text containing:
9483trdcvge245621jde
9483trdcvge245621jdelong
9483trdcvge245621
9483trdcvge245621jde
and run with arguments of:
data/fixedlengthdata.text 2 5 1 9 3
it produces output of:
94,83trd,c,vge245621,jde
94,83trd,c,vge245621,jde
short input line "9483trdcvge245621" skipped
94,83trd,c,vge245621,jde
(where the third line above goes to stderr, of course.)
This is probably the most bizzare requirement that I've ever seen, but anyway...
Psuedo-code
Collection<Integer> indexes; // initialized with indexes to add commas at
StringBuilder bldr = new StringBuilder();
for (int i = 0; i < inString.length(); i++){
bldr.append(inString.charAt(i));
if (indexes.contains(i))
bldr.append(",");
}
return bldr.toString();

Categories

Resources