-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathUnderScorifySubstring.java
More file actions
172 lines (141 loc) · 5.27 KB
/
UnderScorifySubstring.java
File metadata and controls
172 lines (141 loc) · 5.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
//Time Complexity O(n+m) <- Amortized Analysis max bound
//Time Complexity O(n^2+m) <- max bound in general but not specific
//Space Complexity O(n)
import java.util.*;
class A
{
public static void main(String[] args)
{
//given the input string and match put under score at left & right of where match appears
//collapse when substrings overlaps or appears together
//i.e for test -> _test_
//for testest -> _testtest_
//for testestest -> _testestest_
String input = "testthis is a testtest to see if testestest it works";
String match = "test";
String result = underScorifySubstring(input,match);
System.out.println("under scorified string is "+result);
}
public static String underScorifySubstring(String str,String match)
{
//first get all locations whwre substring appears
//store the starting and ending index od the substring (wrt to given string str)
//then call collapse method to take care of overlapping & joined substrings
ArrayList<int[]> locations = collapse(getLocations(str,match));
//put underscorify at given locations
return underScorifySubstringHelper(str,locations);
}
public static String underScorifySubstringHelper(String str,ArrayList<int[]> locations)
{
//to tarverse locations
int locationsIdx = 0;
//to traverse String str
int startIdx = 0;
//if we are in between underscire then we accept value at first index of array stored in locations arraylist
//else we access value stored in 0 index of array stored in locationc arraylist
boolean inbetweenUnderScores = false;
//final generated string to be returned
StringBuffer finalString = new StringBuffer();
//it will switch value between o & 1 to access values stored in array stored in locations arraylist
//if inbetweenunderscore is true then i is 1 & vice versa
int i = 0;
while(startIdx<str.length() && locationsIdx < locations.size())
{
//if we are at a point in string where we should insert underscore
if(startIdx == locations.get(locationsIdx)[i])
{
//insert underscore
finalString.append("_");
//flip the inbetweenunderscores value
inbetweenUnderScores = (!inbetweenUnderScores);
//go to next location of substring if we are not inbwetween substring
//i.e if we are inbetween substring we must access value at 1 index in array stored in ArrayList
//then we will move to next array in ArrayList
if(!inbetweenUnderScores)
{
locationsIdx++;
}
//flip the value of i
i = (i==1?0:1);
}
//append other characters in the input string to final string to be returned
finalString.append(str.charAt(startIdx));
//increment the pointer of string str
startIdx++;
}
//if we break from while loop due to startIdx > str.length()
//if there are more locations where underscore to be added (i.e last underscore of a string if any)
if(locationsIdx < locations.size())
{
//add that underscore
finalString.append("_");
}
//if we break from while loop due to locationIdx > locations
else if(startIdx < str.length())
{
//append the remaining charcaters of the string to the finalstring to be returned
finalString.append(str.substring(startIdx,str.length()));
}
//conver the StringBuffer to String and return it
return finalString.toString();
}
public static ArrayList<int[]> collapse(ArrayList<int[]> locations)
{
//collapse method collapse the overlapping ranges
//i.e [0,4] [1,5] is collapsed to [0,5]
if(locations.size()==0)
{
return locations;
}
ArrayList<int[]> newLocation = new ArrayList<int[]>();
newLocation.add(locations.get(0));
int[] previous = newLocation.get(0);
for(int i =1 ; i < locations.size() ; i++)
{
int[] current = locations.get(i);
if(current[0]<= previous[1])
{
previous[1]=current[1];
}
else
{
newLocation.add(current);
previous = current;
}
}
return newLocation;
}
//get Locations of all occurances of String match in given String str
public static ArrayList<int[]> getLocations(String str,String match)
{
//to store locations of all the occuraces
//first inedx of int[] stores the starting index of substring
//second ondex stores the ending index of substring (excluded)
//ArrayList is a coolection of locations of all substrings
ArrayList<int[]> locations = new ArrayList<int[]>();
int startIdx = 0;
//uterate the given string str
while(startIdx< str.length())
{
//nextIdx to iterate is the occurance of first substring in given string
//indexOf returns -1 if no substring found
//returns starting index of first encountered substring in given string
int nextIdx = str.indexOf(match,startIdx);
if(nextIdx != -1)
{
//if substring found then add its coordinate to array list
// startIdx will be known endIdx will be startIdx + its length (susbstring length)
locations.add(new int[]{nextIdx,nextIdx+match.length()});
//increment startIdx to the letter next to first letter of appeared substring in given string
startIdx = nextIdx+1;
}
//break if no substring found
else
{
break;
}
}
//return the location
return locations;
}
}