insane
insane

Reputation: 729

Splitting a number pattern

I want to now how do i split a string like 44664212666666 into [44664212 , 666666] or 58834888888888 into [58834, 888888888] without knowing where the first occurrence of the last recurring digit occurs. so passing it to a function say seperate(str) --> [non_recurring_part, end_recurring digits]

Upvotes: 0

Views: 139

Answers (8)

KDjava
KDjava

Reputation: 2455

start iterating from the end,towards the initial digit, just get the position where the character occurring changes, that should be the limit for sub string splitting, Let that limit index is--> i, Then Your Result will be-->{sub-string [0,i) , sub-string [i,size)},, That will solve your problem..

         int pos=0;
    String str="ABCDEF";
    for (int i = str.length()-1; i > 0; i--)
    {
        if(str.charAt(i) != str.charAt(i-1))
        {
            pos=i;
            break;
        }
    }

    String sub1=str.substring(0, pos);
    String sub2=str.substring(pos);

Upvotes: 0

georg
georg

Reputation: 214969

print re.findall(r'^(.+?)((.)\3+)$', '446642126666')[0][:-1] # ('44664212', '6666')

As pointed out in the comments, the last group should be made optional to handle strings with no repeated symbols correctly:

print re.findall(r'^(.+?)((.)\3+)?$', '12333')[0][:-1] # ('12', '333')
print re.findall(r'^(.+?)((.)\3+)?$', '123')[0][:-1]   # ('123', '')

Upvotes: 5

Steven Rumbalski
Steven Rumbalski

Reputation: 45541

Here is a non-regex answer that deals with cases when there are no repeating digits.

def separate(s):
    last = s[-1]
    t = s.rstrip(last)
    if len(t) + 1 == len(s):
        return (s, '')
    else:
        return t, last * (len(s) - len(t))

Examples:

>>> separate('123444')
('123', '444')
>>> separate('1234')
('1234', '')
>>> separate('11111')
('', '11111')

Upvotes: 1

Igor Chubin
Igor Chubin

Reputation: 64573

>>> import re
>>> m = re.match(r'(.*?)((.)\3+)$', '1233333')
>>> print list(m.groups())[:2]
['12', '33333']

Here you use regular expressions. The last part of the re ((.)\3+)$ says that the same number must be repeated till the end of the string. And all the rest is the first part of the string. The function m.groups() return the list of the string that correspond to the () parts of the re. The 0 element contains the first part; the 1 element contains the second part. The third part is not needed, we can just ignore it.

Another important point is ? in .*?. Using the symbol you say that you need non-greedy search. That means that you need to switch to the second part of re as soon as possible.

Upvotes: 0

Emmanuel
Emmanuel

Reputation: 14209

Same answer as Justin:

>>> for i in range(len(s) - 1, 0, -1):
    if s[i] != s[-1]:
        break


>>> non_recurring_part, end_recurring_digits = s[:i], s[i + 1:]
>>> non_recurring_part, end_recurring_digits
('4466421', '666666')

Upvotes: 1

Marco de Wit
Marco de Wit

Reputation: 2804

def seperate(s):
 return re.findall('^(.+?)('+s[-1]+'+)$',s)

Upvotes: 0

Fred Foo
Fred Foo

Reputation: 363627

def separate(n):
    s = str(n)
    return re.match(r'^(.*?)((.)\3*)$', s).groups()

Upvotes: 0

Justin
Justin

Reputation: 4216

Can't you just scan from the last character to the first character and stop when the next char doesn't equal the previous. Then split at that index.

Upvotes: 0

Related Questions