コード例 #1
0
 bool wordBreak(string s, unordered_set<string>& wordDict) {
     int len = s.length();
     if (len == 0) return false;
     vector<bool> isBreakable(len+1, false);
     isBreakable[len] = true;
     int minLen = INT_MAX, maxLen = INT_MIN;
     for (string word : wordDict) {
         minLen = min(minLen, (int)word.length());
         maxLen = max(maxLen, (int)word.length());
     }
     for (int i = len - minLen; i >= 0; --i) {
         for (int j = minLen; j <= min(maxLen, len - i); ++j) {
             if (isBreakable[i + j] && wordDict.count(s.substr(i, j))) {
                 isBreakable[i] = true;
                 break;
             }
         }
     }
     return isBreakable[0];
 }
コード例 #2
0
std::unique_ptr<Lines> createLines(RenderBlockFlow& flow)
{
    auto lines = std::make_unique<Lines>();

    RenderText& textRenderer = toRenderText(*flow.firstChild());
    ASSERT(!textRenderer.firstTextBox());

    const RenderStyle& style = *flow.style();
    const unsigned textLength = textRenderer.textLength();

    float wordTrailingSpaceWidth = style.font().width(TextRun(&space, 1));

    LazyLineBreakIterator lineBreakIterator(textRenderer.text(), style.locale());
    int nextBreakable = -1;

    unsigned lineEndOffset = 0;
    while (lineEndOffset < textLength) {
        lineEndOffset = skipWhitespaces(textRenderer, lineEndOffset, textLength);
        unsigned lineStartOffset = lineEndOffset;
        unsigned runEndOffset = lineEndOffset;
        LineWidth lineWidth(flow, false, DoNotIndentText);
        while (runEndOffset < textLength) {
            ASSERT(!isWhitespace(textRenderer.characterAt(runEndOffset)));

            bool previousWasSpaceBetweenRuns = runEndOffset > lineStartOffset && isWhitespace(textRenderer.characterAt(runEndOffset - 1));
            unsigned runStartOffset = previousWasSpaceBetweenRuns ? runEndOffset - 1 : runEndOffset;

            ++runEndOffset;
            while (runEndOffset < textLength) {
                if (runEndOffset > lineStartOffset && isBreakable(lineBreakIterator, runEndOffset, nextBreakable, false))
                    break;
                ++runEndOffset;
            }

            unsigned runLength = runEndOffset - runStartOffset;
            bool includeEndSpace = runEndOffset < textLength && textRenderer.characterAt(runEndOffset) == ' ';
            float wordWidth;
            if (includeEndSpace)
                wordWidth = textWidth(textRenderer, runStartOffset, runLength + 1, lineWidth.committedWidth(), style) - wordTrailingSpaceWidth;
            else
                wordWidth = textWidth(textRenderer, runStartOffset, runLength, lineWidth.committedWidth(), style);

            lineWidth.addUncommittedWidth(wordWidth);
            if (!lineWidth.fitsOnLine()) {
                if (!lineWidth.committedWidth()) {
                    lineWidth.commit();
                    lineEndOffset = runEndOffset;
                }
                break;
            }
            lineWidth.commit();
            lineEndOffset = runEndOffset;
            runEndOffset = skipWhitespaces(textRenderer, runEndOffset, textLength);
        }
        if (lineStartOffset == lineEndOffset)
            continue;

        Line line;
        line.textOffset = lineStartOffset;
        line.textLength = lineEndOffset - lineStartOffset;
        line.width = lineWidth.committedWidth();

        lines->append(line);
    }

    textRenderer.clearNeedsLayout();

    lines->shrinkToFit();
    return lines;
}
コード例 #3
0
std::unique_ptr<Layout> create(RenderBlockFlow& flow)
{
    RenderText& textRenderer = toRenderText(*flow.firstChild());
    ASSERT(!textRenderer.firstTextBox());

    const RenderStyle& style = flow.style();
    const unsigned textLength = textRenderer.textLength();

    ETextAlign textAlign = style.textAlign();
    float wordTrailingSpaceWidth = style.font().width(TextRun(&space, 1));

    LazyLineBreakIterator lineBreakIterator(textRenderer.text(), style.locale());
    int nextBreakable = -1;

    Layout::RunVector runs;
    unsigned lineCount = 0;

    unsigned lineEndOffset = 0;
    while (lineEndOffset < textLength) {
        lineEndOffset = skipWhitespaces(textRenderer, lineEndOffset, textLength);
        unsigned lineStartOffset = lineEndOffset;
        unsigned wordEndOffset = lineEndOffset;
        LineWidth lineWidth(flow, false, DoNotIndentText);

        Vector<Run, 4> lineRuns;
        lineRuns.uncheckedAppend(Run(lineStartOffset, 0));

        while (wordEndOffset < textLength) {
            ASSERT(!isWhitespace(textRenderer.characterAt(wordEndOffset)));

            bool previousWasSpaceBetweenWords = wordEndOffset > lineStartOffset && isWhitespace(textRenderer.characterAt(wordEndOffset - 1));
            unsigned wordStartOffset = previousWasSpaceBetweenWords ? wordEndOffset - 1 : wordEndOffset;

            ++wordEndOffset;
            while (wordEndOffset < textLength) {
                if (wordEndOffset > lineStartOffset && isBreakable(lineBreakIterator, wordEndOffset, nextBreakable, false))
                    break;
                ++wordEndOffset;
            }

            unsigned wordLength = wordEndOffset - wordStartOffset;
            bool includeEndSpace = wordEndOffset < textLength && textRenderer.characterAt(wordEndOffset) == ' ';
            float wordWidth;
            if (includeEndSpace)
                wordWidth = textWidth(textRenderer, wordStartOffset, wordLength + 1, lineWidth.committedWidth(), style) - wordTrailingSpaceWidth;
            else
                wordWidth = textWidth(textRenderer, wordStartOffset, wordLength, lineWidth.committedWidth(), style);

            lineWidth.addUncommittedWidth(wordWidth);

            // Move to the next line if the current one is full and we have something on it.
            if (!lineWidth.fitsOnLine() && lineWidth.committedWidth())
                break;

            if (wordStartOffset > lineEndOffset) {
                // There were more than one consecutive whitespace.
                ASSERT(previousWasSpaceBetweenWords);
                // Include space to the end of the previous run.
                lineRuns.last().textLength++;
                lineRuns.last().right += wordTrailingSpaceWidth;
                // Start a new run on the same line.
                lineRuns.append(Run(wordStartOffset + 1, lineRuns.last().right));
            }

            lineWidth.commit();

            lineRuns.last().right = lineWidth.committedWidth();
            lineRuns.last().textLength = wordEndOffset - lineRuns.last().textOffset;

            lineEndOffset = wordEndOffset;
            wordEndOffset = skipWhitespaces(textRenderer, wordEndOffset, textLength);

            if (!lineWidth.fitsOnLine()) {
                // The first run on the line overflows.
                ASSERT(lineRuns.size() == 1);
                break;
            }
        }
        if (lineStartOffset == lineEndOffset)
            continue;

        adjustRunOffsets(lineRuns, textAlign, lineWidth.committedWidth(), lineWidth.availableWidth());

        for (unsigned i = 0; i < lineRuns.size(); ++i)
            runs.append(lineRuns[i]);

        runs.last().isEndOfLine = true;
        ++lineCount;
    }

    textRenderer.clearNeedsLayout();

    return Layout::create(runs, lineCount);
}
コード例 #4
0
ファイル: Arbitre.cpp プロジェクト: Mulverick/Gomoku
bool Arbitre::checkWinner(Vector<int> const &pos, char const * const *map, int color, bool recusive)
{
	int	nb;
	Vector<int> next = pos;
	if (((color == BLACK ? _prisoner[0] : _prisoner[1])) >= 10)
	{
		_isWinner = true;
		_winner = color;
		return true;
	}
	nb = 1;
	++next.x;
	while (next.x < 19 && map[next.y][next.x] == color)
	{
		if (recusive) checkWinner(next, map, color, false);
		++next.x;
		++nb;
	}
	next.x = pos.x - 1;
	while (next.x >= 0 && map[next.y][next.x] == color)
	{
		if (recusive) checkWinner(next, map, color, false);
		--next.x;
		++nb;
	}
	if (nb >= 5)
	{
		++next.x;
		if (_ruleOptionalEnd == false)
		{
			_isWinner = true;
			return true;
		}
		else if (_ruleOptionalEnd == true && isBreakable(next, map, color, nb, Vector<int>(1, 0)) == false)
		{
			_isWinner = true;
			return true;
		}
	}
	nb = 1;
	next.x = pos.x;
	next.y = pos.y + 1;
	while (next.y < 19 && map[next.y][next.x] == color)
	{
		if (recusive) checkWinner(next, map, color, false);
		++next.y;
		++nb;
	}
	next.y = pos.y - 1;
	while (next.y >= 0 && map[next.y][next.x] == color)
	{
		if (recusive) checkWinner(next, map, color, false);
		--next.y;
		++nb;
	}
	if (nb >= 5)
	{
		++next.y;
		if (_ruleOptionalEnd == false)
		{
			_isWinner = true;
			return true;
		}
		else if (_ruleOptionalEnd == true && isBreakable(next, map, color, nb, Vector<int>(0, 1)) == false)
		{
			_isWinner = true;
			return true;
		}
	}
	nb = 1;
	next.x = pos.x + 1;
	next.y = pos.y + 1;
	while (next.x < 19 && next.y < 19 && map[next.y][next.x] == color)
	{
		if (recusive) checkWinner(next, map, color, false);
		++next.x;
		++next.y;
		++nb;
	}
	next.x = pos.x - 1;
	next.y = pos.y - 1;
	while (next.x >= 0 && next.y >= 0 && map[next.y][next.x] == color)
	{
		if (recusive) checkWinner(next, map, color, false);
		--next.x;
		--next.y;
		++nb;
	}
	if (nb >= 5)
	{
		++next.x;
		++next.y;
		if (_ruleOptionalEnd == false)
		{
			_isWinner = true;
			return true;
		}
		else if (_ruleOptionalEnd == true && isBreakable(next, map, color, nb, Vector<int>(1, 1)) == false)
		{
			_isWinner = true;
			return true;
		}
	}
	nb = 1;
	next.x = pos.x - 1;
	next.y = pos.y + 1;
	while (next.x >= 0 && next.y < 19 && map[next.y][next.x] == color)
	{
		if (recusive) checkWinner(next, map, color, false);
		--next.x;
		++next.y;
		++nb;
	}
	next.x = pos.x + 1;
	next.y = pos.y - 1;
	while (next.x < 19 && next.y >= 0 && map[next.y][next.x] == color)
	{
		if (recusive) checkWinner(next, map, color, false);
		++next.x;
		--next.y;
		++nb;
	}
	if (nb >= 5)
	{
		--next.x;
		++next.y;
		if (_ruleOptionalEnd == false)
		{
			_isWinner = true;
			return true;
		}
		else if (_ruleOptionalEnd == true && isBreakable(next, map, color, nb, Vector<int>(-1, 1)) == false)
		{
			_isWinner = true;
			return true;
		}
	}
	return (false);
}