The Longest Straight

最长顺子牌算法解析
本文介绍了一种解决特定纸牌游戏中寻找最长连续序列(顺子)问题的算法。通过输入玩家手中的牌(包括普通牌和可以替代任意值的百搭牌),该算法能够找出能形成的最长顺子的长度。文章详细解释了算法的工作原理,并提供了完整的实现代码。

Description

ZB is playing a card game where the goal is tom make straights. Each card in the deck has a number between 1 and M, inclusive. A straight is a sequence of cards with consecutive values. Values do not wrap around, so 1 does not come after M. In addition to regular cards, the deck also contains jokers. Each joker can be used as any valid number (between 1 and M, inclusive).

You will be giben N integers card[1]...card[n] referring to the cards in your hand. Jokers are represented by zeros, and other cards are represented by their values. ZB wants to know the number of cards in the longest straight that can be formed using one or more cards from his hand.

Input

The first line contains an integer T, meaning the number of the cases.

For each test case:

The first line there are two integers N and M in the first line (1 <= N, M <= 105), and the second line contains N integers card[i](0 <= card[i] <= M).

Output

For each test case, output a single integer a line -- the longest straight ZB can get.

Sample Input

2
7 11
0 6 5 3 0 10 11
8 1000
100 100 100 101 100 99 97 103

Sample Output

5
3



#include <stdio.h>  
#include <string.h>  
int main(){  
    int T;  
    int a[100001], N, M, flag[100001], joker;  
    scanf("%d", &T);  
    while(T--){  
        joker = 0;  
        memset(a, 0, sizeof(a));  
        scanf("%d %d", &N, &M);  
        for(int i = 0; i < N; i++){  
            int temp;  
            scanf("%d", &temp);  
            if(temp)  
                a[temp] = 1;  
            else
                ++joker;  
        }  
        flag[0] = 0;  
        for(int i = 1; i <= M; i++){  
            if(a[i]){  
                flag[i] = flag[i-1];  
            }  
            else{  
                flag[i] = flag[i-1] + 1;  
            }  
        }  
        int ans = 0;  
        for(int i = 0; i <= M; i++){  
            int left = i, right = M, mid;  
            while(left <= right){  
                mid = (left + right) / 2;  
                if(flag[mid] - flag[i] > joker){  
                    right = mid - 1;  
                }  
                else{  
                    left = mid + 1;  
                }  
            }  
            if(right - i > ans){  
                ans = right - i;  
            }  
        }  
        printf("%d\n", ans);  
    }  
    return 0;  
}  

根据上面代码再结合下面代码写出完整的文本文档管理 // // MODULE: TextDocument.cpp // // PURPOSE: Basic implementation of a text data-sequence class // // NOTES: www.catch22.net // #define STRICT #define WIN32_LEAN_AND_MEAN #include <windows.h> #include "TextDocument.h" #include "TextView.h" #include "Unicode.h" struct _BOM_LOOKUP BOMLOOK[] = { // define longest headers first { 0x0000FEFF, 4, NCP_UTF32 }, { 0xFFFE0000, 4, NCP_UTF32BE }, { 0xBFBBEF, 3, NCP_UTF8 }, { 0xFFFE, 2, NCP_UTF16BE }, { 0xFEFF, 2, NCP_UTF16 }, { 0, 0, NCP_ASCII }, }; // // TextDocument constructor // TextDocument::TextDocument() { // buffer = 0; m_nDocLength_bytes = 0; m_nDocLength_chars = 0; m_pLineBuf_byte = 0; m_pLineBuf_char = 0; m_nNumLines = 0; m_nFileFormat = NCP_ASCII; m_nHeaderSize = 0; } // // TextDocument destructor // TextDocument::~TextDocument() { clear(); } // // Initialize the TextDocument with the specified file // bool TextDocument::init(TCHAR *filename) { HANDLE hFile; hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); if(hFile == INVALID_HANDLE_VALUE) return false; return init(hFile); } // // Initialize using a file-handle // bool TextDocument::init(HANDLE hFile) { ULONG numread; char *buffer; if((m_nDocLength_bytes = GetFileSize(hFile, 0)) == 0) return false; // allocate new file-buffer if((buffer = new char[m_nDocLength_bytes]) == 0) return false; // read entire file into memory ReadFile(hFile, buffer, m_nDocLength_bytes, &numread, 0); m_seq.init((BYTE *)buffer, m_nDocLength_bytes); // try to detect if this is an ascii/unicode/utf8 file m_nFileFormat = detect_file_format(&m_nHeaderSize); // work out where each line of text starts if(!init_linebuffer()) clear(); CloseHandle(hFile); delete[] buffer; return true; } // Initialize the TextDocument with the specified file // /*bool TextDocument::save(TCHAR *filename) { HANDLE hFile; hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); if(hFile == INVALID_HANDLE_VALUE) return false; CloseHandle(hFile); return true; }*/ // // Parse the file lo // // // From the unicode.org FAQ: // // 00 00 FE FF UTF-32, big-endian // FF FE 00 00 UTF-32, little-endian // FE FF UTF-16, big-endian // FF FE UTF-16, little-endian // EF BB BF UTF-8 // // Match the first x bytes of the file against the // Byte-Order-Mark (BOM) lookup table // int TextDocument::detect_file_format(int *m_nHeaderSize) { BYTE header[4] = { 0 }; m_seq.render(0, header, 4); for(int i = 0; BOMLOOK[i].len; i++) { if(m_nDocLength_bytes >= BOMLOOK[i].len && memcmp(header, &BOMLOOK[i].bom, BOMLOOK[i].len) == 0) { *m_nHeaderSize = BOMLOOK[i].len; return BOMLOOK[i].type; } } *m_nHeaderSize = 0; return NCP_ASCII; // default to ASCII } // // Empty the data-TextDocument // bool TextDocument::clear() { m_seq.clear(); m_nDocLength_bytes = 0; if(m_pLineBuf_byte) { delete[] m_pLineBuf_byte; m_pLineBuf_byte = 0; } if(m_pLineBuf_char) { delete[] m_pLineBuf_char; m_pLineBuf_char = 0; } m_nNumLines = 0; return true; } bool TextDocument::EmptyDoc() { clear(); m_seq.init(); // this is not robust. it's just to get the thing // up-and-running until I write a proper line-buffer mananger m_pLineBuf_byte = new ULONG[0x1000]; m_pLineBuf_char = new ULONG[0x1000]; m_pLineBuf_byte[0] = 0; m_pLineBuf_char[0] = 0; return true; } // // Return a UTF-32 character value // int TextDocument::getchar(ULONG offset, ULONG lenbytes, ULONG *pch32) { // BYTE *rawdata = (BYTE *)(buffer + offset + m_nHeaderSize); BYTE rawdata[16]; lenbytes = min(16, lenbytes); m_seq.render(offset+ m_nHeaderSize, rawdata, lenbytes); #ifdef UNICODE UTF16 *rawdata_w = (UTF16 *)rawdata;//(WCHAR*)(buffer + offset + m_nHeaderSize); WCHAR ch16; size_t ch32len = 1; switch(m_nFileFormat) { case NCP_ASCII: MultiByteToWideChar(CP_ACP, 0, (CCHAR*)rawdata, 1, &ch16, 1); *pch32 = ch16; return 1; case NCP_UTF16: return utf16_to_utf32(rawdata_w, lenbytes / 2, pch32, &ch32len) * sizeof(WCHAR); case NCP_UTF16BE: return utf16be_to_utf32(rawdata_w, lenbytes / 2, pch32, &ch32len) * sizeof(WCHAR); case NCP_UTF8: return utf8_to_utf32(rawdata, lenbytes, pch32); default: return 0; } #else *pch32 = (ULONG)(BYTE)rawdata[0]; return 1; #endif } // // Fetch a buffer of UTF-16 text from the specified byte offset - // returns the number of characters stored in buf // // Depending on how Neatpad was compiled (UNICODE vs ANSI) this function // will always return text in the "native" format - i.e. Unicode or Ansi - // so the necessary conversions will take place here. // // TODO: make sure the CR/LF is always fetched in one go // make sure utf-16 surrogates kept together // make sure that combining chars kept together // make sure that bidirectional text kep together (will be *hard*) // // offset - BYTE offset within underlying data sequence // lenbytes - max number of bytes to process (i.e. to limit to a line) // buf - UTF16/ASCII output buffer // plen - [in] - length of buffer, [out] - number of code-units stored // // returns - number of bytes processed // ULONG TextDocument::gettext(ULONG offset, ULONG lenbytes, TCHAR *buf, ULONG *buflen) { // BYTE *rawdata = (BYTE *)(buffer + offset + m_nHeaderSize); ULONG chars_copied = 0; ULONG bytes_processed = 0; if(offset >= m_nDocLength_bytes) { *buflen = 0; return 0; } while(lenbytes > 0 && *buflen > 0) { BYTE rawdata[0x100]; size_t rawlen = min(lenbytes, 0x100); // get next block of data from the piece-table m_seq.render(offset + m_nHeaderSize, rawdata, rawlen); // convert to UTF-16 size_t tmplen = *buflen; rawlen = rawdata_to_utf16(rawdata, rawlen, buf, &tmplen); lenbytes -= rawlen; offset += rawlen; bytes_processed += rawlen; buf += tmplen; *buflen -= tmplen; chars_copied += tmplen; } *buflen = chars_copied; return bytes_processed; //ULONG remaining = lenbytes; //int charbuflen = *buflen; //while(remaining) /* { lenbytes = min(lenbytes, sizeof(rawdata)); m_seq.render(offset + m_nHeaderSize, rawdata, lenbytes); #ifdef UNICODE switch(m_nFileFormat) { // convert from ANSI->UNICODE case NCP_ASCII: return ascii_to_utf16(rawdata, lenbytes, buf, (size_t*)buflen); case NCP_UTF8: return utf8_to_utf16(rawdata, lenbytes, buf, (size_t*)buflen); // already unicode, do a straight memory copy case NCP_UTF16: return copy_utf16((WCHAR*)rawdata, lenbytes/sizeof(WCHAR), buf, (size_t*)buflen); // need to convert from big-endian to little-endian case NCP_UTF16BE: return swap_utf16((WCHAR*)rawdata, lenbytes/sizeof(WCHAR), buf, (size_t*)buflen); // error! we should *never* reach this point default: *buflen = 0; return 0; } #else switch(m_nFileFormat) { // we are already an ASCII app, so do a straight memory copy case NCP_ASCII: int len; len = min(*buflen, lenbytes); memcpy(buf, rawdata, len); *buflen = len; return len; // anything else is an error - we cannot support Unicode or multibyte // character sets with a plain ASCII app. default: *buflen = 0; return 0; } #endif // remaining -= lenbytes; // buf += lenbytes; // offset += lenbytes; }*/ } ULONG TextDocument::getdata(ULONG offset, BYTE *buf, size_t len) { //memcpy(buf, buffer + offset + m_nHeaderSize, len); m_seq.render(offset + m_nHeaderSize, buf, len); return len; } // // Initialize the line-buffer // // With Unicode a newline sequence is defined as any of the following: // // \u000A | \u000B | \u000C | \u000D | \u0085 | \u2028 | \u2029 | \u000D\u000A // bool TextDocument::init_linebuffer() { ULONG offset_bytes = 0; ULONG offset_chars = 0; ULONG linestart_bytes = 0; ULONG linestart_chars = 0; ULONG bytes_left = m_nDocLength_bytes - m_nHeaderSize; ULONG buflen = m_nDocLength_bytes - m_nHeaderSize; // allocate the line-buffer for storing each line's BYTE offset if((m_pLineBuf_byte = new ULONG[buflen+1]) == 0) return false; // allocate the line-buffer for storing each line's CHARACTER offset if((m_pLineBuf_char = new ULONG[buflen+1]) == 0) return false; m_nNumLines = 0; // loop through every byte in the file for(offset_bytes = 0; offset_bytes < buflen; ) { ULONG ch32; // get a UTF-32 character from the underlying file format. // this needs serious thought. Currently ULONG len = getchar(offset_bytes, buflen - offset_bytes, &ch32); offset_bytes += len; offset_chars += 1; if(ch32 == '\r') { // record where the line starts m_pLineBuf_byte[m_nNumLines] = linestart_bytes; m_pLineBuf_char[m_nNumLines] = linestart_chars; linestart_bytes = offset_bytes; linestart_chars = offset_chars; // look ahead to next char len = getchar(offset_bytes, buflen - offset_bytes, &ch32); offset_bytes += len; offset_chars += 1; // carriage-return / line-feed combination if(ch32 == '\n') { linestart_bytes = offset_bytes; linestart_chars = offset_chars; } m_nNumLines++; } else if(ch32 == '\n' || ch32 == '\x0b' || ch32 == '\x0c' || ch32 == 0x0085 || ch32 == 0x2029 || ch32 == 0x2028) { // record where the line starts m_pLineBuf_byte[m_nNumLines] = linestart_bytes; m_pLineBuf_char[m_nNumLines] = linestart_chars; linestart_bytes = offset_bytes; linestart_chars = offset_chars; m_nNumLines++; } // force a 'hard break' else if(offset_chars - linestart_chars > 128) { m_pLineBuf_byte[m_nNumLines] = linestart_bytes; m_pLineBuf_char[m_nNumLines] = linestart_chars; linestart_bytes = offset_bytes; linestart_chars = offset_chars; m_nNumLines++; } } if(buflen > 0) { m_pLineBuf_byte[m_nNumLines] = linestart_bytes; m_pLineBuf_char[m_nNumLines] = linestart_chars; m_nNumLines++; } m_pLineBuf_byte[m_nNumLines] = buflen; m_pLineBuf_char[m_nNumLines] = offset_chars; return true; } // // Return the number of lines // ULONG TextDocument::linecount() { return m_nNumLines; } // // Return the length of longest line // ULONG TextDocument::longestline(int tabwidth) { //ULONG i; ULONG longest = 0; ULONG xpos = 0; // char *bufptr = (char *)(buffer + m_nHeaderSize); /* for(i = 0; i < length_bytes; i++) { if(bufptr[i] == '\r') { if(bufptr[i+1] == '\n') i++; longest = max(longest, xpos); xpos = 0; } else if(bufptr[i] == '\n') { longest = max(longest, xpos); xpos = 0; } else if(bufptr[i] == '\t') { xpos += tabwidth - (xpos % tabwidth); } else { xpos ++; } } longest = max(longest, xpos);*/ return 100;//longest; } // // Return information about specified line // bool TextDocument::lineinfo_from_lineno(ULONG lineno, ULONG *lineoff_chars, ULONG *linelen_chars, ULONG *lineoff_bytes, ULONG *linelen_bytes) { if(lineno < m_nNumLines) { if(linelen_chars) *linelen_chars = m_pLineBuf_char[lineno+1] - m_pLineBuf_char[lineno]; if(lineoff_chars) *lineoff_chars = m_pLineBuf_char[lineno]; if(linelen_bytes) *linelen_bytes = m_pLineBuf_byte[lineno+1] - m_pLineBuf_byte[lineno]; if(lineoff_bytes) *lineoff_bytes = m_pLineBuf_byte[lineno]; return true; } else { return false; } } // // Perform a reverse lookup - file-offset to line number // bool TextDocument::lineinfo_from_offset(ULONG offset_chars, ULONG *lineno, ULONG *lineoff_chars, ULONG *linelen_chars, ULONG *lineoff_bytes, ULONG *linelen_bytes) { ULONG low = 0; ULONG high = m_nNumLines-1; ULONG line = 0; if(m_nNumLines == 0) { if(lineno) *lineno = 0; if(lineoff_chars) *lineoff_chars = 0; if(linelen_chars) *linelen_chars = 0; if(lineoff_bytes) *lineoff_bytes = 0; if(linelen_bytes) *linelen_bytes = 0; return false; } while(low <= high) { line = (high + low) / 2; if(offset_chars >= m_pLineBuf_char[line] && offset_chars < m_pLineBuf_char[line+1]) { break; } else if(offset_chars < m_pLineBuf_char[line]) { high = line-1; } else { low = line+1; } } if(lineno) *lineno = line; if(lineoff_bytes) *lineoff_bytes = m_pLineBuf_byte[line]; if(linelen_bytes) *linelen_bytes = m_pLineBuf_byte[line+1] - m_pLineBuf_byte[line]; if(lineoff_chars) *lineoff_chars = m_pLineBuf_char[line]; if(linelen_chars) *linelen_chars = m_pLineBuf_char[line+1] - m_pLineBuf_char[line]; return true; } int TextDocument::getformat() { return m_nFileFormat; } ULONG TextDocument::size() { return m_nDocLength_bytes; } TextIterator TextDocument::iterate(ULONG offset_chars) { ULONG off_bytes = charoffset_to_byteoffset(offset_chars); ULONG len_bytes = m_nDocLength_bytes - off_bytes; //if(!lineinfo_from_offset(offset_chars, 0, linelen, &offset_bytes, &length_bytes)) // return TextIterator(); return TextIterator(off_bytes, len_bytes, this); } // // // TextIterator TextDocument::iterate_line(ULONG lineno, ULONG *linestart, ULONG *linelen) { ULONG offset_bytes; ULONG length_bytes; if(!lineinfo_from_lineno(lineno, linestart, linelen, &offset_bytes, &length_bytes)) return TextIterator(); return TextIterator(offset_bytes, length_bytes, this); } TextIterator TextDocument::iterate_line_offset(ULONG offset_chars, ULONG *lineno, ULONG *linestart) { ULONG offset_bytes; ULONG length_bytes; if(!lineinfo_from_offset(offset_chars, lineno, linestart, 0, &offset_bytes, &length_bytes)) return TextIterator(); return TextIterator(offset_bytes, length_bytes, this); } ULONG TextDocument::lineno_from_offset(ULONG offset) { ULONG lineno = 0; lineinfo_from_offset(offset, &lineno, 0, 0, 0, 0); return lineno; } ULONG TextDocument::offset_from_lineno(ULONG lineno) { ULONG lineoff = 0; lineinfo_from_lineno(lineno, &lineoff, 0, 0, 0); return lineoff; } // // Retrieve an entire line of text // ULONG TextDocument::getline(ULONG nLineNo, TCHAR *buf, ULONG buflen, ULONG *off_chars) { ULONG offset_bytes; ULONG length_bytes; ULONG offset_chars; ULONG length_chars; if(!lineinfo_from_lineno(nLineNo, &offset_chars, &length_chars, &offset_bytes, &length_bytes)) { *off_chars = 0; return 0; } gettext(offset_bytes, length_bytes, buf, &buflen); *off_chars = offset_chars; return buflen; } // // Convert the RAW buffer in underlying file-format to UTF-16 // // // utf16len - [in/out] on input holds size of utf16str buffer, // on output holds number of utf16 characters stored // // returns bytes processed from rawdata // size_t TextDocument::rawdata_to_utf16(BYTE *rawdata, size_t rawlen, TCHAR *utf16str, size_t *utf16len) { switch(m_nFileFormat) { // convert from ANSI->UNICODE case NCP_ASCII: return ascii_to_utf16(rawdata, rawlen, (UTF16 *)utf16str, utf16len); case NCP_UTF8: return utf8_to_utf16(rawdata, rawlen, (UTF16 *)utf16str, utf16len); // already unicode, do a straight memory copy case NCP_UTF16: rawlen /= sizeof(TCHAR); return copy_utf16((UTF16 *)rawdata, rawlen, (UTF16 *)utf16str, utf16len) * sizeof(TCHAR); // need to convert from big-endian to little-endian case NCP_UTF16BE: rawlen /= sizeof(TCHAR); return swap_utf16((UTF16 *)rawdata, rawlen, (UTF16 *)utf16str, utf16len) * sizeof(TCHAR); // error! we should *never* reach this point default: *utf16len = 0; return 0; } } // // Converts specified UTF16 string to the underlying RAW format of the text-document // (i.e. UTF-16 -> UTF-8 // UTF-16 -> UTF-32 etc) // // returns number of WCHARs processed from utf16str // size_t TextDocument::utf16_to_rawdata(TCHAR *utf16str, size_t utf16len, BYTE *rawdata, size_t *rawlen) { switch(m_nFileFormat) { // convert from UTF16 -> ASCII case NCP_ASCII: return utf16_to_ascii((UTF16 *)utf16str, utf16len, rawdata, rawlen); // convert from UTF16 -> UTF8 case NCP_UTF8: return utf16_to_utf8((UTF16 *)utf16str, utf16len, rawdata, rawlen); // already unicode, do a straight memory copy case NCP_UTF16: *rawlen /= sizeof(TCHAR); utf16len = copy_utf16((UTF16 *)utf16str, utf16len, (UTF16 *)rawdata, rawlen); *rawlen *= sizeof(TCHAR); return utf16len; // need to convert from big-endian to little-endian case NCP_UTF16BE: *rawlen /= sizeof(TCHAR); utf16len = swap_utf16((UTF16 *)utf16str, utf16len, (UTF16 *)rawdata, rawlen); *rawlen *= sizeof(TCHAR); return utf16len; // error! we should *never* reach this point default: *rawlen = 0; return 0; } } // // Insert UTF-16 text at specified BYTE offset // // returns number of BYTEs stored // ULONG TextDocument::insert_raw(ULONG offset_bytes, TCHAR *text, ULONG length) { BYTE buf[0x100]; ULONG buflen; ULONG copied; ULONG rawlen = 0; ULONG offset = offset_bytes+ m_nHeaderSize; while(length) { buflen = 0x100; copied = utf16_to_rawdata(text, length, buf, (size_t *)&buflen); // do the piece-table insertion! if(!m_seq.insert(offset, buf, buflen)) break; text += copied; length -= copied; rawlen += buflen; offset += buflen; } m_nDocLength_bytes = m_seq.size(); return rawlen; } ULONG TextDocument::replace_raw(ULONG offset_bytes, TCHAR *text, ULONG length, ULONG erase_chars) { BYTE buf[0x100]; ULONG buflen; ULONG copied; ULONG rawlen = 0; ULONG offset = offset_bytes + m_nHeaderSize; ULONG erase_bytes = count_chars(offset_bytes, erase_chars); while(length) { buflen = 0x100; copied = utf16_to_rawdata(text, length, buf, (size_t *)&buflen); // do the piece-table replacement! if(!m_seq.replace(offset, buf, buflen, erase_bytes)) break; text += copied; length -= copied; rawlen += buflen; offset += buflen; erase_bytes = 0; } m_nDocLength_bytes = m_seq.size(); return rawlen; } // // Erase is a little different. Need to work out how many // bytes the specified number of UTF16 characters takes up // ULONG TextDocument::erase_raw(ULONG offset_bytes, ULONG length) { /*TCHAR buf[0x100]; ULONG buflen; ULONG bytes; ULONG erase_bytes = 0; ULONG erase_offset = offset_bytes; while(length) { buflen = min(0x100, length); bytes = gettext(offset_bytes, 0x100, buf, &buflen); erase_bytes += bytes; offset_bytes += bytes; length -= buflen; } // do the piece-table deletion! if(m_seq.erase(erase_offset + m_nHeaderSize, erase_bytes)) { m_nDocLength_bytes = m_seq.size(); return length; }*/ ULONG erase_bytes = count_chars(offset_bytes, length); if(m_seq.erase(offset_bytes + m_nHeaderSize, erase_bytes)) { m_nDocLength_bytes = m_seq.size(); return length; } return 0; } // // return number of bytes comprising 'length_chars' characters // in the underlying raw file // ULONG TextDocument::count_chars(ULONG offset_bytes, ULONG length_chars) { switch(m_nFileFormat) { case NCP_ASCII: return length_chars; case NCP_UTF16: case NCP_UTF16BE: return length_chars * sizeof(WCHAR); default: break; } ULONG offset_start = offset_bytes; while(length_chars && offset_bytes < m_nDocLength_bytes) { TCHAR buf[0x100]; ULONG charlen = min(length_chars, 0x100); ULONG bytelen; bytelen = gettext(offset_bytes, m_nDocLength_bytes - offset_bytes, buf, &charlen); length_chars -= charlen; offset_bytes += bytelen; } return offset_bytes - offset_start; } ULONG TextDocument::byteoffset_to_charoffset(ULONG offset_bytes) { switch(m_nFileFormat) { case NCP_ASCII: return offset_bytes; case NCP_UTF16: case NCP_UTF16BE: return offset_bytes / sizeof(WCHAR); case NCP_UTF8: case NCP_UTF32: case NCP_UTF32BE: // bug bug! need to implement this. default: break; } return 0; } ULONG TextDocument::charoffset_to_byteoffset(ULONG offset_chars) { switch(m_nFileFormat) { case NCP_ASCII: return offset_chars; case NCP_UTF16: case NCP_UTF16BE: return offset_chars * sizeof(WCHAR); case NCP_UTF8: case NCP_UTF32: case NCP_UTF32BE: default: break; } ULONG lineoff_chars; ULONG lineoff_bytes; if(lineinfo_from_offset(offset_chars, 0, &lineoff_chars, 0, &lineoff_bytes, 0)) { return count_chars(lineoff_bytes, offset_chars - lineoff_chars) + lineoff_bytes; } else { return 0; } } // // Insert text at specified character-offset // ULONG TextDocument::insert_text(ULONG offset_chars, TCHAR *text, ULONG length) { ULONG offset_bytes = charoffset_to_byteoffset(offset_chars); return insert_raw(offset_bytes, text, length); } // // Overwrite text at specified character-offset // ULONG TextDocument::replace_text(ULONG offset_chars, TCHAR *text, ULONG length, ULONG erase_len) { ULONG offset_bytes = charoffset_to_byteoffset(offset_chars); return replace_raw(offset_bytes, text, length, erase_len); } // // Erase text at specified character-offset // ULONG TextDocument::erase_text(ULONG offset_chars, ULONG length) { ULONG offset_bytes = charoffset_to_byteoffset(offset_chars); return erase_raw(offset_bytes, length); } bool TextDocument::Undo(ULONG *offset_start, ULONG *offset_end) { ULONG start, length; if(!m_seq.undo()) return false; start = m_seq.event_index() - m_nHeaderSize; length = m_seq.event_length(); *offset_start = byteoffset_to_charoffset(start); *offset_end = byteoffset_to_charoffset(start+length); m_nDocLength_bytes = m_seq.size(); return true; } bool TextDocument::Redo(ULONG *offset_start, ULONG *offset_end) { ULONG start, length; if(!m_seq.redo()) return false; start = m_seq.event_index() - m_nHeaderSize; length = m_seq.event_length(); *offset_start = byteoffset_to_charoffset(start); *offset_end = byteoffset_to_charoffset(start+length); m_nDocLength_bytes = m_seq.size(); return true; }
07-02
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值