UVA 10132 - File Fragmentation

本文介绍了一种解决文件碎片问题的算法。该算法通过对比不同文件碎片的特征来重组原始文件,适用于所有文件相同且每份文件恰好断裂为两部分的情况。输入包含一系列二进制字符串形式的文件碎片,输出则是原始文件的比特模式。

File Fragmentation

The Problem

Your friend, a biochemistry major, tripped while carrying a tray of computer files through the lab. All of the files fell to the ground and broke. Your friend picked up all the file fragments and called you to ask for help putting them back together again.

Fortunately, all of the files on the tray were identical, all of them broke into exactly two fragments, and all of the file fragments were found. Unfortunately, the files didn't all break in the same place, and the fragments were completely mixed up by their fall to the floor.

You've translated the original binary fragments into strings of ASCII 1's and 0's, and you're planning to write a program to determine the bit pattern the files contained.

Input

The input begins with a single positive integer on a line by itself indicating the number of the cases following, each of them as described below. This line is followed by a blank line, and there is also a blank line between two consecutive inputs.

Input will consist of a sequence of ``file fragments'', one per line, terminated by the end-of-file marker. Each fragment consists of a string of ASCII 1's and 0's.

Output

For each test case, the output must follow the description below. The outputs of two consecutive cases will be separated by a blank line.

Output is a single line of ASCII 1's and 0's giving the bit pattern of the original files. If there are 2N fragments in the input, it should be possible to concatenate these fragments together in pairs to make N copies of the output string. If there is no unique solution, any of the possible solutions may be output.

Your friend is certain that there were no more than 144 files on the tray, and that the files were all less than 256 bytes in size.

Sample Input

1

011
0111
01110
111
0111
10111

Sample Output

01110111

================================

每次输入完毕后都会再输入一个空行……每组输出之间也要有空行……

先排序,总长度就是a[0]和a[n-1]的长度和。

长度相等的最多有两个(不会有两个文件在同一个地方断掉),所以只要出现有长度相等的ab,和与它们对应的长度相等的两个cd一定可以组成两份相同的原文件。只有ac ad bc bd四种方式,枚举即可。

如果都只出现一次,那么a[0]和a[n-1]、a[1]和a[n-2]一定可以组成两份相同的原文件,同样枚举即可。


#include <iostream>
#include <string>
#include <cstring>
#include <cstdio>
#include <algorithm>

using namespace std;

string str[333],s1,s2;
char s[333];

int cmp(string a,string b)
{
    if(a.length()==b.length())
        return a<b;
    else return a.length()<b.length();
}

int main()
{
    int t;
    scanf("%d",&t);
    getchar();
    getchar();
    while(t--)
    {
        int n=0,p=-1;
        while(gets(s))
        {
            if(s[0]!='\0')
                str[n++]=s;
            else break;
        }
        sort(str,str+n,cmp);
        //for(int i=0;i<n;i++) cout<<"---"<<str[i]<<endl;
        int sumlen=str[0].length()+str[n-1].length();
        for(int i=0;i<n-1;i++)
        {
            if(str[i].length()==str[i+1].length())
            p=i;
            break;
        }
        if(p!=-1)
        {
            if(str[p]+str[n-1-p]==str[p+1]+str[n-2-p]) cout<<str[p]+str[n-1-p]<<endl;
            else if(str[p]+str[n-1-p]==str[n-2-p]+str[p+1]) cout<<str[p]+str[n-1-p]<<endl;
            else if(str[n-1-p]+str[p]==str[p+1]+str[n-2-p]) cout<<str[n-1-p]+str[p]<<endl;
            else if(str[n-1-p]+str[p]==str[n-2-p]+str[p+1]) cout<<str[n-1-p]+str[p]<<endl;
        }
        else
        {
            if(str[0]+str[n-1]==str[1]+str[n-2]) cout<<str[0]+str[n-1]<<endl;
            else if(str[0]+str[n-1]==str[n-2]+str[1]) cout<<str[0]+str[n-1]<<endl;
            else if(str[n-1]+str[0]==str[1]+str[n-2]) cout<<str[n-1]+str[0]<<endl;
            else if(str[n-1]+str[0]==str[n-2]+str[1]) cout<<str[n-1]+str[0]<<endl;
        }
        if(t) cout<<endl;
    }
    return 0;
}


<think>嗯,用户深入询问了Redis中allocator_frag_bytes指标的含义,这需要结合内存分配机制来解释。从对话历史和引用材料看,用户已经具备Redis内存模型的基础知识,但需要更底层的分配器细节。 用户引用的材料[1]明确指出allocator_frag_bytes是分配器级别的内存碎片量,单位字节。这个指标比mem_fragmentation_ratio更能反映真实碎片情况,因为后者受RSS影响包含进程间共享内存等干扰因素。 需要向用户强调三个关键点:第一,allocator_frag_bytes直接来自jemalloc/tcmalloc等底层分配器,表示已分配但未被有效利用的内存间隙;第二,这与mem_fragmentation_bytes不同,后者是进程级统计;第三,当这个值持续增长时,说明存在内存浪费。 考虑到用户的技术水平,准备用仓库货架的比喻说明内存碎片:把allocator_active比作整个仓库面积,allocator_allocated是实际存放的货物,allocator_frag_bytes就是货架之间的空隙。这样用户能直观理解为什么这个指标很重要。 另外注意到用户上次提问时关注过MEMORY STATS命令,这次问题其实是上次的延续。因此在回答末尾特意保留了相关扩展问题,帮助用户系统掌握Redis内存优化知识。用户似乎对运维实践特别感兴趣,所以补充了activedefrag的阈值建议。 最后检查了所有Redis版本差异,确认allocator_frag_bytes从4.0开始就存在表述一致。避免对用户造成版本混淆。 </think>以下是关于Redis中`allocator_frag_bytes`内存指标的详细解析: ### 一、`allocator_frag_bytes` 核心定义 1. **本质含义** 表示**分配器级别的内存碎片量**(单位字节),由公式计算: $$allocator\_frag\_bytes = allocator\_active - allocator\_allocated$$ 其中: - `allocator_allocated`:Redis分配器实际分配的总内存(含内部碎片)[^1] - `allocator_active`:分配器活动页中的字节量(含外部碎片)[^1] 2. **与碎片率的关联** 该指标是**真实碎片值**的量化体现,区别于碎片率: - `mem_fragmentation_ratio`(进程级):受RSS影响,包含共享库等干扰 - `allocator_frag_ratio`(分配器级):$allocator\_active \div allocator\_allocated$,精确反映碎片程度[^1] --- ### 二、内存碎片构成图示 ```plaintext 物理内存页 (allocator_active) ├── 有效数据 (allocator_allocated) ├── 外部碎片间隙 (allocator_frag_bytes) └── 可释放空白页 (通过 MEMORY PURGE 回收) ``` --- ### 三、关键运维场景分析 | 场景 | 表现特征 | 处理建议 | |-------------------------------|-----------------------------------|----------------------------| | 低字节高碎片率 | `allocator_frag_bytes` < 10MB 但 `allocator_frag_ratio` > 1.5 | **无需处理**,属正常波动[^1] | | 持续增长的`allocator_frag_bytes` | 伴随`allocator_frag_ratio` > 1.8 | 开启`activedefrag yes`[^1] | | 突发性碎片飙升 | 短时写入大量变长数据(如LIST/HASH)| 监控`active_defrag_running`状态[^1] | --- ### 四、相关命令实践 ```bash # 查看完整内存分配细节(含allocator_frag_bytes) redis-cli MEMORY STATS # 手动释放空白页(需jemalloc 5+) redis-cli MEMORY PURGE # 监控碎片整理状态 redis-cli INFO MEMORY | grep active_defrag_running ``` > ⚠️ 注意:`MEMORY PURGE`仅适用于**jemalloc分配器**,且可能引发短暂延迟[^1] ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值