The idea of the program is that it gets the text divided by space from the scanner.
I need to write a method to create an array from text, delete duplicates and return an array of the words which are used only once and don't have duplicates.
I can't find out how to make a new array of unique words. Using only simple and basic construction without HashSet etc.*
For example:
a b a b c a b d
result:
c d
public static String Dublicate(String text) {
String[] dublic = text.split(" ");
String result="";
for (int i = 0; i < dublic.length; i++) {
for (int j = i + 1; j < dublic.length; j++)
if (dublic[i].equals(dublic[j]))
dublic[j] = "delete";
}
for (String s: dublic) {
if (s !="delete") {
result =result + s + " ";
}
}
return result;
}
Split By Space
For splitting by space we can use the split() method & can pass the Space string ("") in the parameter.
String[] texts = text.split(" ");
Delete The duplicate elements
If We can use java 1.8 or greater than 1.8, we can use stream API for getting distinct elements like.
Arrays.stream(texts).distinct().toArray(String[]::new);
Or if we need to implement it with java 1.7, we can use HashSet for getting distinct elements like.
String[] distinctElements = new HashSet<String>(Arrays.asList(texts)).toArray(new String[0]);
The final Source code can be like this:
public static String[] textToArray1_7(String text) {
//split by space
String[] texts = text.split(" ");
//Distinct value
return Arrays.stream(texts).distinct().toArray(String[]::new);
}
public static String[] textToArray1_8(String text) {
//split by space
String[] texts = text.split(" ");
//Distinct value
return new HashSet<String>(Arrays.asList(texts)).toArray(new String[0]);
}
If any further question, can ask for more clarification.
You forgot to mark i-th element as duplicate in case when it really is. See my comments in the below code
public static String Dublicate(String text) {
String[] dublic = text.split(" ");
String result="";
for (int i=0; i<dublic.length; i++){
if (dublic[i].equals("delete")) { // Minor optimization:
// skip elements that are already marked
continue;
}
boolean isDub = false; // we need to track i-th element
for(int j=i+1; j<dublic.length; j++) {
if (dublic[i].equals(dublic[j])) {
dublic[j] = "delete";
isDub = true; // i-th element is also a duplicate...
}
}
if (isDub) {
dublic[i] = "delete"; // ...so you should also mark it
}
}
for(String s: dublic){
if(!s.equals("delete")) { // for strings you should use "!equals" instead of "!="
result = result + s + " ";
}
}
return result;
}
P.S. if original text contains "delete" the result will be incorrect since you use "delete" as a reserved marker word
If the array of unique strings needs to be returned, then the initial array of strings after the splitting the input has to be compacted to exclude invalid values, and a smaller copy needs to be returned:
public static String[] uniques(String text) {
String[] words = text.split(" ");
int p = 0; // index/counter of unique elements
for (int i = 0; i < words.length; i++) {
String curr = words[i];
if (null == curr) {
continue;
}
boolean dupFound = false;
for (int j = i + 1; j < words.length; j++) {
if (null == words[j]) {
continue;
}
if (curr.equals(words[j])) {
words[j] = null;
dupFound = true;
}
}
if (dupFound) {
words[i] = null;
} else {
words[p++] = words[i]; // shift unique elements to the start of array
}
}
return Arrays.copyOf(words, p);
}
If the array of unique strings is returned, it may be conveniently converted into String using String::join as shown below in the test.
Test:
System.out.println(Arrays.toString(uniques("a b a b c a b d")));
System.out.println(String.join(" ", uniques("a b a b c a b d")));
Output
[c, d]
c d
Is there any helper method or utility that actually gives me union of two strings.
For instance, if i have two strings as below:
String s1 = "Isabella,tom,hardy";
String s2 = "Isabella,tom,hardy,victor,smith";
I'm looking for a solution which will take above two strings as input and outputs the result as below:
General syntax: s1.{method/utility}(s2);
output : Isabella,tom,hardy,victor,smith
First, there is no method or utility provided by JDK to address the problem so straight forward.
Second, just for this simple utility importing a 3rd party jar or dependency is not a wise choice.
In this case its always a wise choice to write your own method of purpose.
public static String mergeString(String s1, String s2) {
//check for null as the method doesnt fall in NPE
if(s1 == null || s2 == null) {
return null;
}
//split the given String to some list
List<String> s1List = Arrays.asList(s1.split(","));
List<String> s2List = Arrays.asList(s2.split(","));
//get a Set and add the list items to it. LinkedHashSet
//is used to maintain the given order.
Set<String> stringSet = new LinkedHashSet<>(s1List);
stringSet.addAll(s2List);
//Then join them using java 8 provided Utility
return String.join(",", stringSet);
}
NB: as you mentioned in the comments you may need this type of utility only once in your project. But despite, this logic should be separated from out of your business method. This will make your code more clean and readable.
You can use org.springframework.util.StringUtils
Add a maven dependency spring-core:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>3.2.8.RELEASE</version>
</dependency>
Use StringUtils:
public static void main(String[] args) {
String s1 = "Isabella,tom,hardy";
String s2 = "Isabella,tom,hardy,victor,smith";
String[] outputArr=StringUtils.mergeStringArrays(s1.split(","),s2.split(","));
String output=StringUtils.arrayToCommaDelimitedString(outputArr);
System.out.println(output);
}
Output:
Isabella,tom,hardy,victor,smith
public void unionString(String s1, String s2){
String[] s1Ar = s1.split(",");
String[] s2Ar = s2.split(",");
HashSet<String> set = new HashSet<String>();
for(int i=0;i<s1Ar.length;i++){
set.add(s1Ar[i]);
}
for(int i=0;i<s2Ar.length;i++){
set.add(s2Ar[i]);
}
Iterator<String> it = set.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
Here's a method that will do the union of two strings. You can also pass it a boolean flag to dictate case sensitivity.
public static String union (String s1, String s2, boolean caseInsensitive)
{
// if either string is null, union is the other string
if (s1 == null)
return s2;
if (s2 == null)
return s1;
// use linked set to keep ordering
Set<String> unique = new LinkedHashSet<>();
// put all words from string 1 into the set
for (String word : s1.split(","))
{
word = word.trim(); // remove surrounding space on word
if (caseInsensitive)
{
word = word.toLowerCase();
}
unique.add(word);
}
// put all words from string 2 into the set
for (String word : s2.split(","))
{
word = word.trim(); // remove surrounding space on word
if (caseInsensitive)
{
word = word.toLowerCase();
}
unique.add(word);
}
// get back the format of comma delimiter for the union
String ret = unique.toString().replaceAll("[\\[\\] ]", "");
return ret;
}
Usage:
public static void main(String args[])
{
String s1 = "Isabella,tom,hardy";
String s2 = "Isabella,tom,hardy,victor,smith";
String union = union(s1, s2, false);
System.out.println(union);
}
Outputs:
Isabella,tom,hardy,victor,smith
You Can Use LinkedHashSet which maintains the insertion Order to get desired output.Below is my code:
public class UnionJava {
static LinkedHashSet<String> hashSetString = new LinkedHashSet<>();
static String s1 = "Isabella,tom,hardy"; static String s2 = "Isabella,tom,hardy,victor,smith";
public static void main(String args[]){
String[] set1 = s1.split(","); String[] set2 = s2.split(",");
for(int i=0; i< set1.length;i++){
hashSetString.add(set1[i]);
}
for(int i=0;i<set2.length;i++){
hashSetString.add(set2[i]);
}
int j=0;
for(Iterator i = hashSetString.iterator(); i.hasNext();){
if(j==0){
System.out.print(i.next());
j++;
}else{
System.out.print(","+i.next());
}
}
}
}
A short version with no sanity checks using LinkedHashSet.
public void printUnion() {
String s1 = "Isabella,tom,hardy";
String s2 = "Isabella,tom,hardy,victor,smith";
Set<String>mySet = new LinkedHashSet<>();
mySet.addAll(Arrays.asList(s1.split(",")));
mySet.addAll(Arrays.asList(s2.split(",")));
mySet.stream().forEach(System.out::println);
}
With the java api, you might try :
public class StringTest {
private String string1 ="";
private String string2 ="";
private List<String> array1 = new ArrayList<String>();
private List<String> array2 = new ArrayList<String>();
private String[] stringa1;
private String[] stringa2;
private int output3 = 0;
private int output4 = 0;
public static void main(String[] args) {
new StringTest().startApp();
}
private void startApp() {
string1 = "Isabella,tom,hardy";
stringa1 = string1.split("\\s+"); //array to split
string2 = "Isabella,tom,hardy,victor,smith";
stringa2 = string2.split("\\s+");
for(int o = 0; o<stringa1.length; o++) {
array1.add(stringa1[o]); //adding to arraylist
}
for(int o = 0; o<stringa2.length; o++) {
array2.add(stringa2[o]);
}
for(int outP = 0; outP<array2.size()+array1.size(); outP++) {
for(output4 = 0; output4<array2.size(); output4++) { //iterating and removing double elements
for(output3 = 0; output3<array1.size(); output3++) {
if(array1.size() > array2.size() && array2.get(output4).equalsIgnoreCase(array1.get(output3))) {
array1.remove(array1.get(output3));
}
if(array1.size() < array2.size() && array2.get(output4).equalsIgnoreCase(array1.get(output3))) {
array2.remove(array2.get(output4));
}
}
}
}
array1.addAll(array2); //merging the lists
for(String outPres1 : array1) {
result += " " + outPres1;
}
System.out.println("This is the output: " + result);
}
String s1 = "Isabella,tom,hardy";
String s2 = "Isabella,tom,hardy,victor,smith";
Set<String> result = new TreeSet<String>();
result.addAll(Arrays.asList(s1.split((","))));
result.addAll(Arrays.asList(s2.split((","))));
System.out.println(result);
Well, someone's got to provide a streams solution:
Stream.of(s1, s2)
.flatMap(Pattern.compile(",")::splitAsStream)
.distinct()
.collect(Collectors.joining(","))
How can I check if elements in my ArrayList are ending with "_bp" and append that suffix when they don't.
It would be great if i don't have to convert my ArrayList into String.
I tried below code:
ArrayList<String> comparingList = new ArrayList<String>();
String search = "_bp";
for (String str : comparingList)
{
if (str.trim().contains(search))
{
// Do Nothing
}
else
{
str.trim().concat("_bp");
//Replace existing value with this concated value to array list
}
}
But I am still not able to append "_bp" in the existing element, also dont want to convert my
comparingList into String.
A smaller code is preferable if possible.
Thanks in advance :)
String a = "test";
System.out.println("1 " + a.concat("_bp"));
System.out.println("2 " + a);
a = a.concat("_bp");
System.out.println("3 " + a);
output:
1 test_bp
2 test
3 test_bp
code like this:
ArrayList<String> comparingList = new ArrayList<String>();
comparingList.add("test1_bp");
comparingList.add("test2");
String search = "_bp";
for (int i = 0; i < comparingList.size(); i++) {
String tmpStr = comparingList.get(i);
if(tmpStr.contains(search)){
//do nothing
}else{
comparingList.set(i, tmpStr+"_bp");
}
}
System.out.println(comparingList);
This worked :)
String search = "_bp";
int i = 0;
for (String str : comparingList)
{
if (str.trim().contains(search))
{
}
else
{
comparingList.set(i, str.trim().concat("_bp"));
}
i++;
}
i am making a project about turing machine and i am having a problem about the how do i replace a character in an certain index of a string
Example: if i input in the initial tape:
stackoverflow
then code in the inputArea like
write 1
the output should be
1tackoverflow
but sadly the output of my code is
11111111111111
I'm trying to get rid of the loop because i know my loop is the problem but how should i do it ?
Here's my code
runButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ActE){
String[] iniTape = iTapeArea.getText().split("");
String[] input = inputArea.getText().split("\n");
for(int i=0;i<input.length;i++)
{
if(input[i].contains("write")==true){
sub = input[i].substring(6, input[i].length());
for(int j=0;j<iniTape.length;j++){
System.out.print(""+iniTape[j].replace(iniTape[j], sub));
}
}
}
}
});
No need to try this hard. You can use
String str = "stackoverflow";
System.out.println(str.replace("" + str.charAt(0), "1"));
Out put:
1tackoverflow
Use replaceAll() method of String class as below
yourString.replaceAll("" + yourString.charAt(index), "1")//index is your index at which you want to replace
""+ is equivalent of doing String.valueOf(yourString.charAt(index))
This might do the trick
String[] iniTape = iTapeArea.getText().split("");
String sub= null;
String temp = null;
String[] input = inputArea.getText().split("\n");
//"test 1\ntest 2\ntest 3".split("\n");
for(int i=0;i<input.length;i++)
{
if(input[i].contains("write")==true){
sub = input[i].substring(6, input[i].length());
iniTape[i+1] = sub;
}
}
StringBuffer buffer = new StringBuffer();
for(String str : iniTape) {
buffer.append(str);
}
System.out.println(buffer.toString());
replace the index value with the required character
I use the replaceFirst(String, String) function of the String class.
public static void main(String[] args) {
String s = "stackoverflow";
s = s.replaceFirst("" + s.charAt(0), "1");
System.out.println(s);
}
If you want to replace a given certain indexes of a string with that number you can do the following
static String str = "stackoverflow";
public static String replaceCharsAt(int ... indices) {
for (int index : indicies) {
str = str.replace(str.charAt(i), i+1);
}
return str;
}
Say I have a String like below
String s1 = "test1=1&test2=2&test3=&test4=4";
Pls note the test3 parameter in the string S1 as it doesn't have any value
String [] splitS1 = s1.split("\\&");
for (int i = 0; i < splitS1.length; i++) {
String[] params = splitS1[i].split("=");
System.out.println("Attribute:"+params[0]+" Value : "+params [1]);
}
Above code throws java.lang.ArrayIndexOutOfBoundsException: 1 because test3 in String s1 doesn't have any value so params[1] is not valid with respect to test3.
I tried doing this
if(params.length == 1) {
params[1] = "";
}
But I know that we can't extend the array. What can be done here?
Thanks!
The split method that takes one parameter discards trailing empty tokens. Here, this results in params having only a length of one.
User the split method that also takes a limit parameter, and pass a negative limit to ensure that you get an array with a length that matches the number of tokens actually present: 2.
String[] params = splitS1[i].split("=", -1);
Then you won't have to create another array; you'll get an array of size 2 to start with, assuming there is an = present.
The easiest thing would be to test the array length:
String splitS1 = s1.split("\\&");
for (int i = 0; i < splitS1.length; i++) {
String[] params = splitS1[i].split("=");
System.out.println(
"Attribute: " + params[0] +
" Value : " + (params.length < 1 ? "<no value>" : params[1]));
}
It might also be worth using printf instead of println:
System.out.printf("Attribute: %1$s%n Value : %2$s%n",
params[0],
params.length < 1 ? "<no value>" : params[1]
);
Create a class representing a parameter, with its name and value and which parses the string:
public final class Parameter {
private final String name;
private final String value;
public Parameter(String name, String value) {
this.name = name;
this.value = value;
}
public static Parameter parse(String s) {
String[] parts = s.split("=");
String name = parts[0];
String value = "";
if (parts.length > 1) {
value = parts[1];
}
return new Parameter(name, value);
}
public String getName() {
return name;
}
public String getValue() {
return value;
}
// add more behavior if needed.
}
And now you can do
for (int i = 0; i < splitS1.length; i++) {
Parameter param = Parameter.parse(splitS1[i]);
System.out.println("Parameter:" + param.getName() + " = " + param.getValue());
}
Create a new String array and copy the result of split into it.
String[] cpy = new String[2];
for(int i=0;i<cpy.length;i++){
cpy[i] = params[i];
}
params = cpy;
You can do some thing like this
String s1 = "test1=1&test2=2&test3=&test4=4";
String[] splitS1 = s1.split("\\&");
for (int i = 0; i < splitS1.length; i++) {
String[] params = splitS1[i].split("=");
String[] para=new String[2];
if(params.length==1) {
para[0]=params[0];
System.out.println("Attribute:"+para[0]+" Value : "+para [1]);
}
else{
System.out.println("Attribute:"+params[0]+" Value : "+params [1]);
}
}
or
if(params.length==1) {
System.out.println("Attribute:"+para[0]+" Value : "+"");
}
else{
System.out.println("Attribute:"+params[0]+" Value : "+params [1]);
}