How can i remove the exact number of middle characters from a string? - string

I am trying to remove the number of middle characters in a string according to a given number. For example, if the string is mahir and I am told to remove one middle character, that would be h and the output would be mair, if the given number was 2, the output would have been mar.
I have worked out how the remove the middle characters but having troubles in removing it correctly. This is my code:
remover = int(input())
s = "mahir"
counter = len(s) - remover
while True:
h = len(s)//2
mod = (len(s) + 1) % 2
s = s[:h - mod] + s[h + 1:]
if len(s) == counter:
break
print(s)
If i enter remover more than one I end up getting an inifinte loop. How can i fix this and remove the correct number of middle characters?

You can slice the string like this:
s = 'mahir'
n = int(input())
i = (len(s) - n + 1) // 2
print(s[:i] + s[i + n:])

Related

Longest sub string and its length without repeated chars

def findLongestSubstring(string):
st = 0 # starting point of current substring.
maxlen = 0 # maximum length substring without repeating characters.
start = 0 # starting index of maximum length substring.
pos = {} # Hash Map to store last occurrence of each already visited character
pos[string[0]] = 0 #Last occurrence of first character is index 0
for i in range(1, len(string)):
# If this character is not present in hash, character, store this in hash.
if string[i] not in pos:
pos[string[i]] = i
else:
# If this character is present in hash then check if that occurrence
# is before or after starting point of current substring.
if pos[string[i]] >= st:
# find length of current substring and update maxlen and start accordingly.
currlen = i - st
if maxlen < currlen:
maxlen = currlen
start = st
# Next substring will start after the last occurrence of current
# character to avoid its repetition.
st = pos[string[i]] + 1
pos[string[i]] = i # Update last occurrence of current character.
# Compare length of last substring with maxlen & update maxlen and start accordingly.
if maxlen < i - st:
maxlen = i - st
start = st
# The required longest substring without repeating characters is from string[start]
#to string[start+maxlen-1].
print("Lenth is:", len(string[start : start + maxlen]) )
print( string[start : start + maxlen] )
return string[start : start + maxlen]
Above code works for the most part. But for below test case, it fail. What am I doing wrong? Code was copied from GeeksforGeeks. Code is returning "ba", instead of "bad".
assert(findLongestSubstring("babad") == "bad" )
Your last length check should work if you increment i by 1.
# Compare length of last substring with maxlen & update maxlen and start accordingly.
if maxlen < (i + 1) - st:
maxlen = (i + 1) - st
start = st

Sorting strings without methods and other types

Hello I have to reorder a string, I am banned from using other types and str methods
So my problem is that I could not figure out how to end my code to get it work with any string
I tried to compare the results with sorted() to check and I am stuck at the first exchange
My code:
i = 0
s1 = "hello"
s2 = sorted(s1)
while (i<len(s1)):
j=i+1
while (j<=len(s1)-1):
if (s1[i] > s1[j]):
s1 = s1[0:i] + s1[j] + s1[i]
j+=1
i+=1
print(s1)
print(s2)
I tried to add + s1[len(s1):] at the end of the operation but
I only had found the result for a single string(that I was testing) adding thisI am really stuck, how can I make it work for all the strings with different lenghts??
Thanks
You're not reconstructing the string correctly when doing s1 = s1[0:i] + s1[j] + s1[i] as you're replacing one character for the other but you omit to actually interchange the two and to add the remains of the splitted string to the end of the new string.
Given what your code looks like, I would do it like this:
i = 0
s1 = "hello"
s2 = sorted(s1)
while i < len(s1):
j = i + 1
while j <= len(s1)-1:
if s1[i] > s1[j]:
s1 = s1[0:i] + s1[j] + s1[i+1:j] + s1[i] + s1[j+1:len(s1)]
j += 1
i += 1
print("".join(s2))
# > 'ehllo'
print(s1)
# > 'ehllo'
Please tell me if anything is unclear!
I am banned from using other types and str methods
Based upon your criteria, your request is impossible. Just accessing the elements of a string requires string methods.
The technique that you are using is very convoluted, hard to read and is difficult to debug. Try running your code in a debugger.
Now given that you are allowed to convert a string to a list (which requires string methods), redesign your code to use simple, easy to understand statements.
The following code first converts the string into a list. Then loops thru the list starting at the beginning and compares each following character to the end. If any character is less then the current character, swap. As you step thru the string, the character swaps will result in a sorted list. At the end convert the list back to a string using join().
msg = 'hello'
s = list(msg)
for i in range(len(s) - 1):
for j in range(i + 1, len(s)):
if s[i] <= s[j]:
continue
# swap characters
s[i], s[j] = s[j], s[i]
print(msg)
print(''.join(s))

replace an occurrence with a distinct number every loop

The first occurrence of the character in the string will be replaced with a 1, the second occurrence with a 2, etc.
ive tried using for loop and the max function to replace the last occurence but it doesnt seem to work.
string=str(input('string: '))
x=input('character: ')
list=[]
for i in range(len(string)):
if string[i]==x:
list.append(i)
Z=str(max(list))
print(string.replace(x,Z,[::-1]))
the output should be as following
string: departmentofcomputerscience
character: e
d1partm2ntofcomput3rsci4nc5
Here's a way to do it.
Use a counter for each character in the loop, and store values in the list, then merge the list. Use the current value if not equal to the character, counter otherwise:
string=str(input('string: '))
x=input('character: ')
# Use list to store results and a counter
l = []
counter = 0
for c in string:
if c==x:
counter += 1
l.append(str(counter))
else:
l.append(c)
# Merge the resulting list into string
res = "".join(l)
# Output the result
print(res)
For the input string: departmentofcomputerscience
and the character: e
The output is
d1partm2ntofcomput3rsci4nc5
Here is another way to achieve the goal using a list and the method replace():
string = str(input('string: '))
x = input('character: ')
list = []
for i in range(len(string)):
if string[i] == x:
list.append(i) # add all indexes to replace to the list
if len(list) > 0:
j = 0
for i in range(len(list)):
j += 1
string = string.replace(string[list[i]], str(j), 1) # replace the element once at time
print(string)
For string: departmentofcomputerscience
character: e
Output: d1partm2ntofcomput3rsci4nc5
def replace(s, c):
'''
#parameter s: input string
#parameter c: input character to be replaced
#return s: where every occurence of c is
replaced by it's nth occurence
'''
so = list(s)
j = 1
for i in range(len(so)):
if so[i] == c:
so[i] = str(j)
j = j + 1
return ''.join(so)

Can someone explain to me why I get empty string as a result?

What im trying to do is get the longest substring in s in which the letters occur in alphabetical order.
For some reason alphasub has no string in it at the end and I don't know why
start = 0
sub = 1
maxsub = 0
current = 0
s = 'azcbobobegghakl'
leng = len(s)
for i in range(leng):
if i != leng - 1:
if s[i] <= s[i+1]:
current = i
sub = 1
while current < (leng-1):
if s[current] <=s [current+1]:
sub += 1
current += 1
else:
break
if(sub>maxsub):
maxsub = sub
start = i
alphasub = s[start:maxsub]
print("longest substring is: " + alphasub)
String slicing takes starting and end position.
https://docs.python.org/2/tutorial/introduction.html
Change alphasub=s[start:maxsub] to alphasub=s[start:start+maxsub]. You should see the expected output.
It's good practice to use print's to check your code.
I've added some prints at the end of your code like so:
print(s)
print(start)
print(maxsub)
alphasub=s[start:maxsub]
print ("longest substring is: " + alphasub)
Which outputs:
azcbobobegghakl
7
5
longest substring is:
It is starting at 7, and ending at 5, which obviously doesn't work.

Is there a pythonic way to insert space characters at random positions of an existing string?

is there a pythonic way to implement this:
Insert /spaces_1/ U+0020 SPACE
characters into /key_1/ at random
positions other than the start or end
of the string.
?
There /spaces_1/ is integer and /key_1/ is arbitrary existing string.
Thanks.
strings in python are immutable, so you can't change them in place. However:
import random
def insert_space(s):
r = random.randint(1, len(s)-1)
return s[:r] + ' ' + s[r:]
def insert_spaces(s):
for i in xrange(random.randrange(len(s))):
s = insert_space(s)
return s
Here's a list based solution:
import random
def insert_spaces(s):
s = list(s)
for i in xrange(len(s)-1):
while random.randrange(2):
s[i] = s[i] + ' '
return ''.join(s)
I'm going to arbitrarily decide you never want two spaces inserted adjacently - each insertion point used only once - and that "insert" excludes "append" and "prepend".
First, construct a list of insertion points...
insert_points = range (1, len (mystring))
Pick out a random selection from that list, and sort it...
import random
selected = random.sample (insert_points, 5)
selected.sort ()
Make a list of slices of your string...
selected.append (len (mystring)) # include the last slice
temp = 0 # start with first slice
result = []
for i in selected :
result.append (mystring [temp:i])
temp = i
Now, built the new string...
" ".join (result)
Just because no one used map yet:
import random
''.join(map(lambda x:x+' '*random.randint(0,1), s)).strip()
This method inserts a given number of spaces to a random position in a string and takes care that there are no double spaces after each other:
import random
def add_spaces(s, num_spaces):
assert(num_spaces <= len(s) - 1)
space_idx = []
space_idx.append(random.randint(0, len(s) - 2))
num_spaces -= 1
while (num_spaces > 0):
idx = random.randint(0, len(s) - 2)
if (not idx in space_idx):
space_idx.append(idx)
num_spaces -= 1
result_with_spaces = ''
for i in range(len(s)):
result_with_spaces += s[i]
if i in space_idx:
result_with_spaces += ' '
return result_with_spaces
If you want to add more than one space, then go
s[:r] + ' '*n + s[r:]
Here it comes...
def thePythonWay(s,n):
n = max(0,min(n,25))
where = random.sample(xrange(1,len(s)),n)
return ''.join("%2s" if i in where else "%s" for i in xrange(len(s))) % tuple(s)
We will randomly choose the locations where spaces will be added - after char 0, 1, ... n-2 of the string (n-1 is the last character, and we will not place a space after that); and then insert the spaces by replacing the characters in the specified locations with (the original character) + ' '. This is along the lines of Steve314's solution (i.e. keeping the assumption that you don't want consecutive spaces - which limits the total spaces you can have), but without using lists.
Thus:
import random
def insert_random_spaces(original, amount):
assert amount > 0 and amount < len(original)
insert_positions = sorted(random.sample(xrange(len(original) - 1), amount))
return ''.join(
x + (' ' if i in insert_positions else '')
for (i, x) in enumerate(original)
)

Resources