I came across this problem :
"It gives a string of round brackets. This string represents a parenthesis that is not necessarily correct. You have available the next move : you can change an open bracket '(' into a close brachet ')' or vice versa. You have to calculate the minimum number of moves needed to make the parenthesis to be correct."
e.g.
)())
answer : 1
First of all, I think that it would be useful to use parsing, but the program doesn't seem to work right.
void X() {
if(first=='(') {
firt=fgetc(fi);
X();
if(first!=')')
er++;
first=fgetc(fi);
}
else {
..
}
}
What would be an idea of beginning?
Thanks
答案 0 :(得分:2)
I would like to propose an algorithm. First the pseudo code:
For each input character C:
If C is '(' then
increment counter
else if counter is 0 then // The closing paren has no matching opening
increment moves // so we "flip" it and counting as the opening
increment counter
else
decrement counter // This closing paren is balanced
end if
end For
// Now the counter is containing the number of unbalanced opening parentheses,
// so we add half of this number to moves, as half of them have to be balanced
moves = moves + counter / 2
return moves
Now in C:
#include <stdio.h>
#include <string.h>
int main(void) {
char input[] = "((((";
int len = strlen(input);
int i;
int moves = 0;
int count = 0;
for (i=0; i < len; i++)
{
if (input[i] == '(')
{
count ++;
}
else
{
if (count == 0)
{
count ++;
moves ++;
}
else
{
count --;
}
}
}
moves += count / 2;
printf("Moves: %d\n", moves);
return 0;
}
You are invited to test it with different inputs here, prove it's correctness or disprove with a counterexample input :)
答案 1 :(得分:1)
Here's one way (in Pascal). Fixes the actual string and shows before and after.
function FixBrackets(s: string): Integer;
var
LeftToProcess, OpenCount: Integer;
I: Integer;
begin
writeln('in:', S);
Result := 0;
LeftToProcess := length(s);
OpenCount := 0;
for I := 1 to LeftToProcess do begin
case S[I] of
'(' :
if LeftToProcess <= OpenCount then begin
// we must close all
S[I] := ')';
inc(Result);
end else
inc(OpenCount);
')' :
if OpenCount = 0 then begin
// we have no open pars to close, so this has to be a new open
S[I] := '(';
inc(Result);
inc(OpenCount);
end else
dec(OpenCount);
end;
dec(LeftToProcess);
end;
writeln('out:', s);
end;
答案 2 :(得分:1)
以下是C ++的答案:
template<class T>
int count_changes(T begin, T end) {
int offset = 0;
int changes = 0;
for (auto it = begin; it != end; ++it) {
if (*it == '(') ++offset;
else --offset;
if (offset < 0) {
offset = 1;
changes++;
}
}
return changes + ((offset + 1) / 2);
}
int main() {
std::string parens { "))(()" };
cout << parens << " : " << count_changes(parens.begin(), parens.end()) << endl;
}