Open In App

Python – Equidistant consecutive characters Strings

Last Updated : 23 Apr, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given a Strings List, extract all the strings, whose consecutive characters are at the common difference in ASCII order.

Input : test_list = [“abcd”, “egil”, “mpsv”, “abd”] 
Output : [‘abcd’, ‘mpsv’] 
Explanation : In mpsv, consecutive characters are at distance 3.

Input : test_list = [“abcd”, “egil”, “mpsw”, “abd”] 
Output : [‘abcd’] 
Explanation : In abcd, consecutive characters are at distance 1. 

Method #1 : Using list comprehension + all()

In this, we check for each character has a common difference using all(), and list comprehension is used to iterate strings.

Python3




# Python3 code to demonstrate working of
# Equidistant consecutive characters Strings
# Using list comprehension + all()
 
# initializing list
test_list = ["abcd", "egil", "mpsv", "abd"]
 
# printing original list
print("The original list is : " + str(test_list))
 
# ord() used to get ASCII value
res = [sub for sub in test_list if all(ord(
    sub[idx + 1]) - ord(sub[idx]) == ord(sub[1]) - ord(sub[0]) for idx in range(0, len(sub) - 1))]
 
# printing result
print("Filtered Strings : " + str(res))


Output

The original list is : ['abcd', 'egil', 'mpsv', 'abd']
Filtered Strings : ['abcd', 'mpsv']

Time Complexity: O(n2
Auxiliary Space: O(n)

Method #2 : Using filter() + lambda + ord() + all()

In this, we perform the task of filtering using filter() and lambda function. The task of ord() is to get ASCII equivalent of each character.

Python3




# Python3 code to demonstrate working of
# Equidistant consecutive characters Strings
# Using list comprehension + all()
 
# initializing list
test_list = ["abcd", "egil", "mpsv", "abd"]
 
# printing original list
print("The original list is : " + str(test_list))
 
# ord() used to get ASCII value
res = [sub for sub in test_list if all(ord(sub[idx + 1]) - ord(sub[idx]) == ord(sub[1]) - ord(sub[0]) for idx in range(0, len(sub) -1 ))]
 
# printing result
print("Filtered Strings : " + str(res))


Output

The original list is : ['abcd', 'egil', 'mpsv', 'abd']
Filtered Strings : ['abcd', 'mpsv']

Time Complexity: O(n2
Auxiliary Space: O(n)

Another approach using set
Here, we first check if the length of the string is less than 3, then we can’t check for equidistant characters, hence we return False.
Then, we calculate the difference between the first two characters and store it in a set.
Next, we iterate through the rest of the string and check if the difference between the current character and the previous character is equal to the first calculated difference, if not we return False.
If the loop finishes without returning False, then we return True as all characters have a common difference.

Python3




#Python3 code to demonstrate working of
#Equidistant consecutive characters Strings
#Using set
def equidistant(string):
# If the length of the string is less than 3,
# then we can't check for equidistant characters
  if len(string) < 3:
    return False
  diff = ord(string[1]) - ord(string[0])
  diff_set = {diff}
  for i in range(1, len(string) - 1):
    curr_diff = ord(string[i + 1]) - ord(string[i])
    if curr_diff not in diff_set:
      return False
  return True
 
#initializing list
test_list = ["abcd", "egil", "mpsv", "abd"]
 
#printing original list
print("The original list is : " + str(test_list))
 
#filtering strings using equidistant()
res = list(filter(equidistant, test_list))
 
#printing result
print("Filtered Strings : " + str(res))


Output

The original list is : ['abcd', 'egil', 'mpsv', 'abd']
Filtered Strings : ['abcd', 'mpsv']

Time Complexity: O(n)
Auxiliary Space: O(n)

Method#3: Using Recursive method.

Algorithm:

  1. Define a function is_equidistant(s) to check if a given string s is equidistant, i.e. if the difference between ASCII values of consecutive characters is the same.
  2. The function checks if the length of the string is less than or equal to 2. If so, it returns True.
  3. Otherwise, it returns the boolean result of comparing the differences between ASCII values of the first two characters and the second two characters, and calling itself recursively on the string without the first character.
  4. Define a function filter_equidistant_strings(test_list) to filter equidistant strings from the given list test_list.
  5. If the list is empty, return an empty list.
  6. If the first string in the list is equidistant, return a list consisting of that string concatenated with the result of calling the function recursively on the rest of the list.
  7. Otherwise, return the result of calling the function recursively on the rest of the list.
  8. Call the function filter_equidistant_strings() on the given test_list.
  9. Print the filtered list.

Python3




#Python3 code to demonstrate working of
#Equidistant consecutive characters Strings
#Using recursive method
def is_equidistant(s):
    if len(s) <= 2: # base case
        return True
    else:
        return ord(s[1]) - ord(s[0]) == ord(s[2]) - ord(s[1]) and is_equidistant(s[1:])
 
def filter_equidistant_strings(test_list):
    if not test_list: # base case
        return []
    elif is_equidistant(test_list[0]):
        return [test_list[0]] + filter_equidistant_strings(test_list[1:])
    else:
        return filter_equidistant_strings(test_list[1:])
 
#initializing list
test_list = ["abcd", "egil", "mpsv", "abd"]
 
#printing original list
print("The original list is : " + str(test_list))
 
#filtering strings using equidistant()
res = filter_equidistant_strings(test_list)
 
#printing result
print("Filtered Strings : " + str(res))


Output

The original list is : ['abcd', 'egil', 'mpsv', 'abd']
Filtered Strings : ['abcd', 'mpsv']

Time complexity: The is_equidistant() function is called on each string in the list, which takes O(n) time for a string of length n. Therefore, the time complexity of filter_equidistant_strings() is O(n^2) in the worst case. However, if the average length of strings in the list is small, the time complexity will be closer to O(n).
Auxiliary Space: The recursive implementation uses O(n) space due to the recursive calls on each string in the list.

Method#4: Using the reduce() function: 

Algorithm:

1.Initialize the list of strings.
2.Use filter function along with lambda function and apply reduce function for each string in the list.
3.The lambda function checks if the difference between ASCII value of consecutive characters is equal to the difference between ASCII value of first two characters.
4.reduce() function will return True if all the elements in the iterable are True, else it will return False.
5.If the result of the lambda function is True for a string, then filter function will include that string in the result list.
Print the result list.

Python3




from functools import reduce
 
test_list = ["abcd", "egil", "mpsv", "abd"]
# printing original list
print("The original list is : " + str(test_list))
 
res = list(filter(lambda x: reduce(lambda a,b: a and b, [ord(x[i+1])-ord(x[i]) == ord(x[1])-ord(x[0]) for i in range(len(x)-1)]), test_list))
# printing result
print("Filtered Strings : " + str(res))
#This code is contributed by Jyothi pinjala


Output

The original list is : ['abcd', 'egil', 'mpsv', 'abd']
Filtered Strings : ['abcd', 'mpsv']

Time complexity: O(n*m), where n is the number of strings in the list and m is the maximum length of the string in the list.

Auxiliary Space: O(k), where k is the length of the longest string in the list. This is because we are storing the result in a list.

Method #5: Using for loop

Algorithm

  1. Initialize an input list of strings.
  2. Create an empty list to store the filtered strings.
  3. Iterate over each string in the input list.
  4. For each string, iterate over each pair of consecutive characters and check if the difference between them is the same as the difference between the first two characters.
  5. If the difference between any pair of consecutive characters is not the same, then the string is not arithmetic and move on to the next string.
  6. If all pairs of consecutive characters have the same difference, then the string is arithmetic and add it to the result list.
  7. Print the result list.

Python3




test_list = ["abcd", "egil", "mpsv", "abd"]
# printing original list
print("The original list is : " + str(test_list))
 
res = []
for x in test_list:
    # check if the difference between consecutive characters is the same
    is_arithmetic = True
    for i in range(len(x)-1):
        if ord(x[i+1]) - ord(x[i]) != ord(x[1]) - ord(x[0]):
            is_arithmetic = False
            break
    # if all differences are the same, add the string to the result list
    if is_arithmetic:
        res.append(x)
 
# printing result
print("Filtered Strings : " + str(res))
#This code is contributed by Vinay pinjala.


Output

The original list is : ['abcd', 'egil', 'mpsv', 'abd']
Filtered Strings : ['abcd', 'mpsv']

The time complexity of this code is O(n * k), where n is the number of strings in the input list, and k is the length of the longest string. The outer loop iterates over n strings, while the inner loop iterates over k-1 pairs of consecutive characters in each string. The ord() function, which returns the ASCII value of a character, takes constant time.

The auxiliary space of this code is O(n), where n is the number of strings in the input list. The space required for the input list and the output list is proportional to the number of strings in the list. The space required for the variables used inside the loop is constant, regardless of the length of the strings. Therefore, the space complexity of the code is proportional to the size of the input list.

Method 7 : uses the zip() function and a set comprehension

steps :

Initialize a list test_list with strings as its elements.
Print the original list using print(“The original list is : ” + str(test_list)).
Initialize an empty list res to store the filtered strings.
Iterate over each string x in test_list using a for loop.
Use the zip() function to create a list of pairs of adjacent characters in the string x.
Calculate the set of differences between adjacent ASCII codes in the string x by subtracting the ASCII code of the first character from the ASCII code of the second character using a set comprehension {ord(y) – ord(x) for x, y in zip(x, x[1:])}. The set comprehension calculates the difference for each pair of adjacent characters in the string x and removes duplicates to obtain a set of unique differences.
Check if the length of the set of differences is equal to 1 using the len() function. If the length is 1, then all the differences are the same, and the string x satisfies the condition.
If the string x satisfies the condition, append it to the list res using the append() method.
After all strings in test_list have been processed, print the filtered strings using print(“Filtered Strings : ” + str(res)).

Python3




# Original list
test_list = ["abcd", "egil", "mpsv", "abd"]
print("The original list is : " + str(test_list))
 
# Using zip() and set comprehension
res = []
for x in test_list:
    diffs = {ord(y) - ord(x) for x, y in zip(x, x[1:])}
    if len(diffs) == 1:
        res.append(x)
 
# Printing the result
print("Filtered Strings : " + str(res))


Output

The original list is : ['abcd', 'egil', 'mpsv', 'abd']
Filtered Strings : ['abcd', 'mpsv']

The time complexity of this approach is O(NM), where N is the length of test_list and M is the length of the longest string in test_list. 

The space complexity of this approach is also O(NM), because the set of differences is stored in memory for each string that is added to the result list res. 



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads